본문 바로가기

전체 글 보기

(54)
4.1 적응자(ADAPTER) 의도 클래스의 인터페이스를 사용자가 기대하는 인터페이스 형태로 적응(변환) 시킨다. 다른 이름 Wrapper(래퍼) 동기 "프로그램이 요청하는 인터페이스 ≠ 툴킷에 정의된 인터페이스" 인 경우 툴킷이 재사용을 목표로 개발되었다고 해도 실제 재사용되지 못할 수가 있다. 그림 편집기를 예로 들어보자. 그림판의 중요한 추상적 개념은 그래픽 객체들이다. 공통된 그래픽 요소에 대한 인터페이스를 추상 클래스 Shape 이라고 정의한다. 그리고 각각의 그래픽 요소들을 Shape의 서브클래스로 정의한다. 즉, 선을 위한 LineShape, 다각형을 위한 PolygonShape 등을 Shape을 상속받아 개발하면 된다. LineShape이나 PolygonShape 과 같은 매우 기본적인 그래픽 요소들은 구현이 비교적 쉽..
1.5 카탈로그 조직화하기 패턴의 목적 · 생성 o 객체의 생성 과정에 관여 · 구조 o 클래스나 객체의 합성 · 행동 o 클래스나 객체들이 상호작용 하는 방법 o 클래스나 객체들이 책임을 분산하는 방법 패턴의 적용 범위 · 클래스 패턴 o 클래스와 서브클래스 간의 관련성을 다루는 패턴 o 관련성은 주로 상속 o 컴파일 타임에 정적으로 결정되는 패턴 · 객체 패턴 o 객체간의 관련성을 다룸 o 런타에 변경할 수 있고, 동적인 패턴 대부분은 객체 패턴이다.
1.3 디자인 패턴 기술하기 설계를 재사용하기 좋게 만들려면 설계를 하기까지의 다양한 결정, 대안, 장단점 등을 고려한 과정도 함께 적어주어야 합니다. -패턴 이름과 분류(Pattern Name and Classification) -의도(Intent) -다른 이름(Also Known As) -동기(Motivation) : 설계 문제를 제시하고, 패턴 안에서 클래스나 객체 구조가 어떻게 문제를 해결하는지 설명해 주는 일종의 시나리오 -활용성(Applicability) -구조(Structure) : 객체 모델링 기법(Object Modeling Technique: OMT)에 기반을 둔 표기법을 이용하여 해당 패턴에서 쓰는 클래스들을 시각적으로 나타냅니다. 또한, 객체 사이에 오가는 요청과 협력 관계의 순차를 표현하기 위해서 상호작용 다..
1.2 스몰토크 MVC를 사용한 디자인 패턴 MVC의 구성요소 모델 : 응용프로그램 객체 뷰 : 스크린에 모델을 디스플레이하는 방법 컨트롤러 : 사용자 인터페이스가 사용자 입력에 반응하는 방법 원래는 하나의 객체인 것을 3가지로 분리 -> 유연성 + 재사용성 증대가 목적 뷰 모델 간의 등록(subscribe)/통지(notify) 프로토콜 각 구성 요소가 독립성을 갖도록 변경(종속성을 없앰) 뷰는 반드시 모델의 state(상태)를 반영하여 모델을 디스플레이한다는 보장(guarantee) 모델의 데이터가 변경 -> 모델이 뷰에게 nofity 각 뷰는 스스로 자신 외형을 변경 이런 디자인을 통해 한 모델을 여러가지 뷰로 표현 가능 뷰/모델이 하나의 객체였다면, 한 모델에 여러가지 뷰를 제공하기 위해 데이터는 같고 인스턴스는 다른 3가지의 모델이 필요했다..
1.1 디자인 패턴이란? • 디자인 패턴 : 기존 환경내에서 반복적로 일어나는 문제들을 설명하고, 그 문제들에 대한 해법의 핵심을 설명한다. ○ 이 해법을 100만 번 이상이라도 재사용할 수 있어야 한다. 하나의 '패턴'에는 4가지 요소가 반드시 들어있다. 1. 패턴 이름(pattern name) : 한 두 단어로 설계 문제와 해법을 서술한다. a. 패턴에 이름을 부여하는 것 = 설계를 추상화 = 설계의 의도를 표현 = 설계에 대해 생각을 쉽게 한다 = 개발자들 간 의사소통이 원활 2. 문제(problem) : 언제 패턴을 사용하는가를 서술 a. 해결해야 할 문제와 그 배경(환경)을 설명 3. 해법(solution) a. 설계를 구성하는 요소 b. 요소들 간의 관계 c. 요소들 간의 책임 d. 요소들 간의 협력 e. 다만, 구체..
항목 45: "호환되는 모든 타입"을 받아들이는 데는 멤버 함수 템플릿이 직방! 스마트 포인터(smart pointer)는 일반적인 포인터처럼 동작하면서, 포인터가 주지못하는 다양한 기능을 제공하는 객체이다. 말만 들어서는 스마트 포인터가 완벽한 일반 포인터의 대체제처럼 들리지만, 스마트 포인터가 절대 대신할 수 없는 일반 포인터만의 특징이 있다. 바로 암시적 변환(implicit conversion)을 지원한다는 점이다. 이런 식의 타입 변환을 사용자 정의 스마트 포인터를 써서 흉내내기란 상당히 어렵다. 위 코드를 보면, 전부 같은 템플릿(SmartPtr)으로 만들어진 인스턴스들인데, 이들 사이에는 어떤 관계도 없기 때문에 컴파일러 입장에서 보면 SmartPtr과 SmartPtr은 완벽히 별개의 클래스이다. 이 변환을 가능하게 할려면 SmartPtr 클래스에서 변환을 지원할 타입에..
항목 44: 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자 템플릿은 코딩 시간 절약, 코드 중복 회피의 두마리 토끼를 한꺼번에 잡아 준다. 하지만 아무 생각 없이 템플릿을 사용하면 코드 비대화(code bloat)가 나타날 수 있다. 이 코드 비대화를 어떻게 하면 방지할 수 있을까? 우선적으로 써 볼 수 있는 방법은, 공통성 및 가변성 분석(commonality and variability analysis)이다. 이름은 좀 거창해보이지만 사실 우리가 항상 해오던 분석 방법이다. 우리가 어떤 함수를 만들고 있다가 무심코 다른 함수를 봤는데, 지금 만들고 있는 함수 구현 중 일부가 다른 함수의 구현에도 똑같이 있다는 사실을 알아챘다고 가정해보자. 당연히 우리는 두 함수로부터 공통 코드를 뽑아내고, 이것을 별도의 새로운 함수에 넣은 후, 이 함수를 기존의 두 함수가 ..
항목 43: 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아두자. 회사에서 메세지를 전송하는 프로그램을 만들고 있다고 가정해보자. 메세지는 암호회될 수도 있고, 비가공텍스트(비암호화) 형태가 될 수도 있다. 만약 어떤 메세지가 어떤 회사로 전송될지를 "컴파일 도중"에 결정할 수 있는 충분한 정보가 있다면, 주저 없이 템플릿 기반의 방법을 쓸 수 있을 것이다. 여기에 덧붙여서 메세지를 보낼 때마다 관련 정보를 로그로 남기고 싶다. 이럴땐 파생 클래스를 사용하면 쉽게 이 기능을 붙일 수 있다. 이 파생 클래스를 자세히 보면, 메시지 전송 함수의 이름(sendClearMsg)이 기본 클래스에 있는 것(sendClear)과 다르다는 것을 알 수 있다. 이러한 설계는 다음과 같은 장점을 가진다. 기본 클래스로부터 물려받은 이름을 파생 클래스에서 가리는 문제(항목 33 참고) 하..
항목 42: typename의 두 가지 의미를 제대로 파악하자 질문: 아래의 두 템플릿 선언문에 쓰인 class와 typename의 차이점이 뭘까요? 답변 : 차이가 없다! 템플릿의 타입 매개변수를 선언할 때는 class와 typename이 완전히 똑같다. 하지만 언제까지나 class와 typename이 똑같으면 이 둘을 구분할 이유가 없다. 이 둘이 다를 때가 언제인지 알아볼려면, 일단 템플릿 안에서 우리가 참조할 수 있는 이름의 종류가 2가지라는 것부터 알아야 한다. 함수 템플릿이 하나 있다고 가정하자. 이 템플릿은 STL과 호환되는 컨테이너를 받아드리도록 만들었고, 이 컨테이너에 담기는 객체는 int에 대입할 수 있다. 이 템플릿이 하는 일은 컨테이너에 담긴 원소들 중 두번째 것의 값을 출력하는 것이다. 여기서 지역변수 iter와 value에 강조 표시를 한다..