달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

1. Intro

: iOS 관련 개발 블로그나 세미나/행사에서 Architecture 주제를 다룰 때, 종종 하는 이야기가 있다. MVC의 C가 비대해져서 MVVM을 도입해보고, VM이 비대해져서 VIP를 도입했다는 것. 예전에는 이런 이야기를 의심없이 받아들였으나, 개발을 할수록 의문이 쌓여갔다. C가 비대해서 도입한 MVVM에서, VM이 비대해졌다면... MVC로 개발하면서 발생한 문제를 잘못 짚은게 아닐까.

 

 개발을 하다보면 Model을 단순한 Data Structure로 작성한 코드를 많이 보았다. 그런 코드에서 Business Logic은 Controller나 ViewModel에 작성되어 있었다. 그러니까, Controller나 ViewModel에서 HTTP 통신을 하고, UserDefault나 내부 DB에서 Data를 가져오거나 저장하는 것이다. 당연히 Controller나 ViewModel은 비대해질 수 밖에 없어보이는데, 이상하지 않은가?

 

 마틴(Robert C Martin)은, 여러 공학에서 Model을 만들어서 검증하는 사례를 이야기하며 Model은 '추상화한 것'이라고 이야기한다(UML 책 참고). 나는 이 이야기에 크게 공감하며, ViewModel은 View를 추상화해야 하고 Model은 Business를 추상화해야 한다고 생각한다. 그래서 Business Logic은 Controller나 ViewModel에 작성하는 것이 잘못됬다고 생각한다. 

 

 Model을 단순한 Data Structure로 작성할 수도 있다. 문제는 왜 Business Logic을 Controller나 ViewModel에 작성하냐는 것이다. 이런 고민을 하면서, MVC나 MVVM을 처음 이야기한 사람은 어떻게 생각했는지 궁금해졌다. 그래서 이번 포스트에서는 MVC를 처음 고안한 사람의 Report를 읽은 후 요약해보고, 향후 다른 포스트에서는 다른 Architecture에 대해서도 정리해보고자 한다.

 

 

 

2. The original MVC reports - Trygve Reenskaug

 

2.1. Intro

: 옛날 1978-79년에, Tregve Reenskaug는 Xerox Palo Alto Research Laboratory (PARC)에서 연구원으로 재직하던 때에, MVC reports를 작성하고 구현했었다. MVC는, 여러 관점에서 사용자들이 Data를 통제할 수 있게 하는 일반적인 문제에 대한 솔루션으로 만들어졌었다. MVC에서 가장 어려웠던 문제 중 하나는, Architecture를 구성하는 Component들의 이름을 정하는 것이다. 처음에는 Thing-Model-View-Editor라고 이름을 지었었다(1979년 5월 12일). 하지만 긴 논의 끝에, Model-View-Controller로 이름을 바꾸게 되었다(1979년 12월 10일).

 

 

2.2 Thing-Model-View-Editor (1979년 5월 12일)

=> Thing-Model-View-Editor는 중요한 부분이 아니라고 생각해서, 아주 간략하게 각 컴포넌트의 정의부분만 정리하고자 한다.

 

- Thing

: 사용자가 관심을 가질만한 것.

 

- Model

: Computing System에서, Model은 Data의 형태로 추상화의 표현. Data를 다루는 방법도 함께 제공되는 Collection으로 보자.

 

- View

: View는 Model을 표시하는 역할을 한다. Thing-Model-View-Editor를 고안해낸 당시, 저자는 Model을 하나 이상의 View에 부착(Attach)시키고 싶었던 것 같다.

 

- Editor

: 사용자와 View간 인터페이스 역할을 한다.

 

 

2.3 Model-View-Controller (1979년 12월 10일)

- Model

: Model은 지식(Knowledge)을 나타낸다. Model은 단일 객체일 수 있고, 객체들의 구조체일 수 있다. Model의 Node는 문제에서 식별가능한 부분으로 나타날 수 있어야 한다. => 말이 좀 어려운데, '문제'가 의미하는 것은 개발로서 해결해야 하는 것으로 생각하면 될 것 같다.

 Model의 Node는 모두 같은 문제 레벨에 있어야 한다. => 이것도 역시 말이 어렵다. 나는, 개발할려는 시스템 또는 시스템의 부분을 여러 Layer로 나눈다고 가정할 때 'Model들은 같은 Layer에 있어야 한다'정도로 이해했다(Robert C Martin의 Clean Archtecture의 Entity Layer에 대한 설명을 보고, 이렇게 생각하게 됬다).

 

- View

: Model의 시각적 표현. View는 View의 Model에 부착(Attach)되고, Model을 표현하기 위해 Model로부터 Data를 얻는다.

 

- Controller

: Controller는 사용자와 System을 잇는 역할을 한다. 사용자에게 출력할 것을 적절한 Message로 바꾸어서 하나 이상의 View에 전달한다던지, 화면에 View들을 적절하게 배치하여 사용자에게 입력을 위한 수단을 제공한다던지 해서, Controller는 사용자에게 필요한 입출력 인터페이스를 제공한다.

 Controller는 View를 보완하지 않는 것이 좋다(원 글에선, Controller가 서로 다른 View 끼리 연결을 하지 말라고 하였음). 그리고 View는 사용자의 입력(마우스 동작, 키보드 입력)을 몰라야 한다. 이를 위해, Message를 View로 보내는 Method는 Controller에 구현한다.

 

- Editor

: Controller는 모든 View에 연결되어 있다. 어떤 View는 Editor라는 특별한 Controller를 제공하는데, Editor는 View에 표시된 정보를 사용자가 수정할 수 있게 한다.

 

 

 

3. 읽은 후, 생각 정리

: The Original은 1979년대에 Trygve Reenskaug가 Xerox에서 사용자를 위한 시스템을 개발할 때, 작성된 글이다. 그래서 The Original MVC에서 제안하는 내용 중 일부는 공감되지 않을 수 있는데, 지금과 그 당시의 시대적 차이를 고려해보자(지금 개발중인 앱과, 당시에 개발중인 시스템의 복잡도는...).

 

 View와 Model이 부착(Attach)된다고 표현한 것이 조금 아쉬웠다. 요즘은, View가 Model의 존재를 몰라야 한다는 것이 일반적으로 받아들여지기 때문이다.

 

 Thing-Model-View-Editor에서의 Model과 Model-View-Controller에서 Model에 대한 역할이나 설명이 크게 달라지지 않았는데, 문서에서 설명한 것처럼 Model에서 Data를 다루는 방법도 제공한다면, 이 당시의 Controller는 역할이 방대하지 않았을 것으로 추측된다.

 

 여담이지만, 일하다보면 ViewController(많은 iOS 개발자들이 MVC의 Controller 역할을 부여함)에서 Network나 Local Database를 통해 Data를 가져오는 코드를 많이 보게 된다. 하지만 The Original MVC에 설명된 내용에 따르면 Data를 다루는 Model의 역할을 Controller에게 넘긴 것으로, Controller의 역할 분배를 잘못한 것으로 볼 수 있지 않을까? 바람직하지 않은 것 같다.

 

 

 

4. Reference

1)Trygve Reenskaug: The original MVC Reports, Oslo, February 12, 2007

:
Posted by syjdev

이전 포스트에 이어서, 작성되는 포스트이다.

 

 

1. Swift String에서의 Unicode

: é문자를 통해, Swift String에서 주의할 점들을 설명하고자 한다. é는 e에 acute accent를 붙인 것인데, 이를 표현하는 방법은 한가지 이상이다. 한 문자를 표현하는 방법이 한가지 이상이면, 비교는 어떻게 할 수 있을까? 표현하는 방법마다 문자의 크기는 같을까? 아래의 코드를 보고 하나씩 알아보자.

 

1
2
3
4
5
6
7
8
9
10
11
let firstString = "\u{00E9}lite"
print("1) output: \(firstString)") // => élite
print("1) count: \(firstString.count)") // => 5
print("1) utf16.count: \(firstString.utf16.count)") // => 5
        
let secondString = "e\u{0301}lite"
print("2) output: \(secondString)") // => élite
print("2) count: \(secondString.count)") // => 5
print("2) utf16.count: \(secondString.utf16.count)") // => 6
 
print("isSame: \(firstString == secondString)") // => true
cs

 

 firstString과 secondString은 lite를 제외한, 나머지 부분이 다르다. 그런데 출력시켜 보면, 둘 다 élite가 출력된다. count도 동일하다. 두 String을 비교한 결과는 true다. 하지만, code unit을 16bits로 하고 count를 보면 firstString과 secondString이 다르다.

 

 firstString과 secondString의 *.utf16.count는 다른데, 어째서 비교한 결과는 같은 것일까? Swift Language Guide에서 이유가 설명되어 있었다(링크).

 

 "Two String values (or two Character values) are considered equal if their extended grapheme clusters are canonically equivalent. Extended grapheme clusters are canonically equivalent if they have the same linguistic meaning and appearance, even if they’re composed from different Unicode scalars behind the scenes."

 

 대략 다음과 같이 해석할 수 있다.

 

 "Swift에서 두 String을 비교할 때 두 String의 Extended Grapheme Clusters가 canonically equivalent하면, 두 String은 equal하다. Extended Grapheme Clusters는 언어학적으로(linguistic) 의미와 형태가 같으면, Canonically Equivalent하다."

 

 Swift Language Guide에 나와있듯이, firstString과 secondString은 다른 Unicode Scalar들로 이루어져 있더라도 언어학적으로 의미와 형태가 같아서 비교한 결과가 True인 것이다.

 

 

 

2. NSString에서의 String 처리

: NSString은 조금 동작이 다르다. 확인을 위해 다음과 같은 코드를 작성했다.

 

1
2
3
4
5
6
7
8
let typecastedFirstString = firstString as NSString
print("1) count: \(typecastedFirstString.length)") // => 5
         
let typecastedSecondString = secondString as NSString
print("2) count: \(typecastedSecondString.length)") // => 6
        
let isSameTypecastedStrings = typecastedFirstString == typecastedSecondString 
// => false
 
cs

 

 Swift Strig에서는 firstString과 secondString의 count는 같았는데, NSString으로 타입 캐스팅한 typecastedFirstString과 typecastedSecondString의 length는 왜 다른 것일까? NSString을 설명하는 Apple 문서에 이유가 설명되어 있었다(링크).

 

 "An NSString object encodes a Unicode-compliant text string, represented as a sequence of UTF-16 code units. All lengths, character indexes, and ranges are expressed in terms of 16-bit platform-endian values, with index values starting at 0."

 

 음... 그러니까 NSString은 UTF-16로 Text를 인코딩한다. NSString의 length와 index, range도 16bit로 인코딩한 값에 따라 계산이 된다.

 

 NSString을 비교하는 'isEqual(to aString: String) -> Bool' 메서드에 대한 설명에서도, 두 String의 Unicode가 동일한지를 비교한다고 설명되어 있다(링크).

 

 

 

3. 마무리 및 참고자료

: 이번 글에서는 String을 비교할 때 주의할 점과, Swift String과 NSString이 어떻게 다른지를 설명했다. 글 중간중간에 삽입한 링크들을 정리하는 것을 끝으로, 이번 글을 마무리하겠다.

 

- Swift 문서의 String Compare

https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#ID298

 

- NSString

https://developer.apple.com/documentation/foundation/nsstring

 

- NSString의 isEqual(to aString: String) -> Bool 메서드

https://developer.apple.com/documentation/foundation/nsstring/1407803-isequal

:
Posted by syjdev

1. Intro

: C로 개발을 처음 공부했을때, 처음 접해본 문자열은 char *message = "hello world";와 같은 형태였다. message는 char들이 저장된 곳의 시작주소이고, 문자열의 맨 마지막은 null이었다. char charArray[4] = { 'a', 'b', 'c', '\0' }; 와 같이, char들의 배열을 선언하고 배열의 마지막 요소를 '\0'로 설정해서 문자열을 나타낼 수도 있었다.

 ASCII Code로 나타낼 수 없는 문자를 표현하기 위해 Unicode가 생겨났고 UTF-8, UTF-16, UTF-32 등의 Encoding이 있다는 것, 문자열에 대한 나의 이해는 이정도였다.

 어느 날 책에서 이런 내용을 보았다. 

"String의 n번째 Character에 접근하는 연산은 time complexity가 o(n)이다. 
String의 n번째 Character에 접근하는 것이 Random Access가 아니기 때문이다".

 부끄럽게도, String을 구성하는 Character들이 배열같은 Collection에 순서대로 저장되어 있을 것이라 생각해서 Array의 요소에 접근하는 것처럼, String의 Character에 접근하는 것도 Random Access로 접근할 것이라고 생각했었다.

 그동안 컴퓨터에서 문자를 어떻게 다루는지에 대한 별다른 고민없이 사용했다는게 조금은 부끄럽기도 해서, 다양한 문서들을 읽어보았다. 이런저런 문서들을 읽어보니 생각보다 알아야 할 것들이 많았고, 익힌 내용을 정리할 필요가 있다고 생각하여 글을 적어보고자 한다.

 

 

2. ASCII의 한계와 그것을 극복하기 위해 등장한 표준들

: ASCII는 매우 단순하다. ASCII 문자로 이루어진 문자열은, 구성하는 Character들이 모두 8bits로 크기가 일정하다. 그래서, 문자열의 Character에 Random Access로 접근할 수 있지만, 미국에서 쓰는 알파벳이 아닌 문자를 표현하는 데에 한계가 있다. 그래서 ISO/IEC 8859 표준이 등장했는데...

 

2-1. ISO/IEC 8859의 등장

: 컴퓨터에서 문자를 8bits로 나타내는 위한 표준. 8번째 비트를 이용해서, 기존의 ASCII보다 더 많은 문자를 표현하여 ASCII의 한계를 극복하려 하였다. ISO 8859-1,2,3, ..., 16까지 있다. 하지만 ISO/IEC 8859 표준도 문자의 크기가 고정되어 있어서 동아시아 국가의 문자를 표현하는 데에는 한계가 있었다. 그래서 등장한 표준이...

 

2-2. Unicode의 등장

: 초기의 Unicode도 2bytes로 크기가 고정되어 있었고, UCS-2 라고 불렀었다. 하지만 2bytes로도 많은 문자들을 표현하는 데에 한계가 있었고, 오늘날에는 Unicode는 문자의 크기가 고정되지 않고 각각 다른 크기를 가질 수 있게 되었다.
=> 이런 이유로, String의 Character에 접근하는 것은 Random Access가 될 수 없다. n번째 Character를 알기 위해선,
n-1까지의 Character들을 확인해야 하기 때문이다.

 

3. Unicode란 무엇일까?

※ 이제부터 문자는 Character, 문자열은 String이라고 표현하겠음.

 

: Charactrer를 Encoding하는 표준을 일컫는 Unicode Standard와 그를 주도하는 협회 Unicode Consortium 모두를 Unicode라고 불리지만, 이 글에서는 Unicode Standard만을 이야기하고자 한다.

 

3-1. Unicode가 등장하기 전 Character 처리

: 기본적으로 컴퓨터는 숫자를 다룬다. 컴퓨터는 각 Character마다 다른 숫자를 할당하여 저장한다. Unicode Standard가 탄생하기 전, 다양한 Character Encoding 방법들이 있었으나 전 세계의 모든 언어를 표현하기엔 한계가 있었다. 특히 동아시아 언어를 표현하는 데에 한계가 있었다(뭐, 한글이라던지).

 초기의 Character Encoding들은 서로간 충돌(Conflict)이 있었다(같은 숫자를 다른 Character로 처리하거나 한 Character를 각기 다른 숫자로 처리하는 것). 컴퓨터들은 다양한 Character Encoding들을 지원했지만, 컴퓨터간 통신시 Character Encoding이 다를 경우, 문제가 발생할 수 있었다.

3-2. Unicode 등장

: 바로 위에서 이런 문제들을 해결하기 위해, Unicode가 만들어졌다.
=> 간단한 Character Encoding을 제공하는 것을 넘어서, Unicode Consortium은 'locale data'에 대한 표준에도 관심을 두고 있다. 

 

3-3. Unicode와 관련된 용어 정리

1) Code Point - 표준문서의 D10
: Unicode code space에 속하는 값. 값의 범위는 0에서 0x10FFFF(10진수로 나타내면 1,114,111)까지이다. Code Point들은 하나의 Character로 표시될 수 있지만, 여러 Code Point들이 모여서 하나의 Character를 표시할 수도 있다.

2) Unicode Scalar - 표준문서의 D76

: Code Point중, High/Low Surrogate를 제외한 것.

3) Surrogate(High Surrogate, Low Surrogate) - 표준문서의 3.8
: Surrogate는, 미래를 위해 Code Point에서 따로 남겨둔 부분이다(Surrogate 개개별로는 Character로 나타내지 않는다). 범위에 따라 High Surrogate와 Low Surrogate로 나뉘어 진다. High Surrogate와 Low Surrogate는 범위가 다른데, 표로 나타내면 다음과 같다.

 

그림1. High Surrogate
그림2. Low Surrogate

 

4) Surrogate Pair

: High Surrogate에 속하는 Code Point 하나와 Low Surrogate에 속하는 Code Point 하나의 Pair로 구성하여 Single Character를 나타내는 것. UTF-16에서만 사용된다.


5) Code Unit

: Encoded Text의 Unit을 나타낼 수 있는 최소 bit 조합. Unicode Standard는 UTF-8에서는 8bits Code Unit들을 사용하고, UTF-16에서는 16bits Code Unit들을 사용하고, UTF-32에서는 32bits Code Unit들을 사용한다.

 

※ 개인적으로 Code Unit과 Code Point가 조금 헷갈렸다. 비교해서 정리해보면,

" Single Code Point는 Single Code Unit일 수 있고, 여러 Code Unit들로 이루어질 수도 있다. "
=> ☃ 는 3개의 UTF-8 Code Unit들로 이루어질 수 있고, 1개의 UTF-16 Code Unit으로 이루어질 수 있다.


6) Code Unit Sequence
: 하나 이상의 Code Unit들로 구성된 Ordered Sequence.


 Programming Language에서 String Data의 값은 기본적으로 Code Unit Sequence로 구성된다. 공식적이진 않지만, Code Unit Sequence 자체를 String이라고 하기도 하고, Byte Sequence를 Byte String이라고 하기도 한다.
=> 공식적으로는 Programming Language에 따라, String은 요구사항이나 복잡성이 추가되기도 한다. 예를 들자면, C Language에서 String은 NULL Character로 끝나야 한다던지. 

 Unicode Encoding Form은 Unicode Scalar 값을 Unicode Code Unit Sequence에 할당한다. 역사적인 이유로, Unicode Encoding Form은 Unicode(또는 UCS) Transformation Format, UTF로 불리기도 한다.

 Unicode Encoding Form에서, Unicode Scalar 값의 Set을 Code Unit Sequence의 Set으로 Mapping할 때, One-To-One으로 Mapping된다.
=> Reverse Mapping시, Mapping되기 전의 값을 추론할 수 있도록 보장한다.

하지만, Onto로 Mapping되는 것은 아니라서 Code Unit Sequence와 연관된 Unicode Scalar 값이 없을 수도 있다.

Unicode Encoding Form이 One-To-One으로 Mapping하는 것을 보장하기 위해, 모든 Unicode Scalar 값은 반드시 Unicode Code Unit Sequence로 Mapping되어야 한다.
=> Surrogate는 예외이다.

7) Unicode String

: 특정한 Unicode Encoding Form의 Code Unit들을 포함하는 Code Unit Sequence. 가장 Raw한 형태의 Unicode String은 적절한 정수들의 배열로, 간단하게 구현될 수 있다.
 단일 Unicode String은 단일 Unicode Encoding Form의 Code Unit만 포함해야 한다. String 내에서 Form을 혼합하는 것은 허용되지 않는다. 따라서...

- Unicode 8bits String, UTF-8 Code Unit들로 이루어진다.
- Unicode 16bits String, UTF-16 Code Unit들로 이루어진다.
- Unicode 32bits String, UTF-32 Code Unit들로 이루어진다.

 

 

4. 마무리 및 참고자료

: 이번 글에서는 Unicode와 관련된 용어를 정리하는 것에 중점을 두었다. Unicode Scalar, Code Point, Code Unit 등 여러 용어가 나왔고 각각에 대해서 간략하게 정리했는데, 더 알고 싶은 분들을 위해 참고했던 자료의 링크를 소개하는 것을 끝으로 이번 글을 마무리하겠다.

 

- Unicode 

https://home.unicode.org/basic-info/

 

- Unicode 12.0 Standard Documents

https://www.unicode.org/versions/Unicode12.0.0/

https://www.unicode.org/versions/Unicode12.0.0/UnicodeStandard-12.0.pdf

 

- Programming with Unicode

https://unicodebook.readthedocs.io/index.html

 

:
Posted by syjdev