No older revisions available
No older revisions available
http://images.amazon.com/images/P/0471958697.01.PE_PIm.arrow,TopLeft,-2,-19_SCMZZZZZZZ_.jpg 0471958697 http://images.amazon.com/images/P/0471606952.01.PE_PIm.arrow,TopLeft,-2,-19_SCMZZZZZZZ_.jpg 0471606952
1. 소개 ¶
- 3가지 다른 레벨(소프트웨어 구조,모든 디자인, idioms)에서 어떻게 패턴이 발생하는지 이 책에 자세히 나와 있다. 이러한 통합적인 접근 다소 이론적일거 같이 보이지만, 저자는 12개의 패턴과 실제로 사용되는 예제를 많이 보여 준다.
- 자세한 소개는 아마존 사이트를 참고 하면 좋습니다.
- 누구나 같이 참여 하시는 분은 대 환영입니다.
- 중간 중간에 해석이 안되는 부분이나 잘못 기술한 부분 있으면 수정해주시면 감사 하겠습니다. ^^;
2.2. 2. Architectual Patterns ¶
- 소프트웨어 구조적인 관점에서 사용되는 패턴들이 나온다.
- 크게 네개의 그룹으로 나눌 수 있다.
그룹 | 사례 패턴 | 설명 |
From Mud to Structure | Layer, Blackboard Pattern | 전체적인 시스템을 상호 협력하는 하부 그룹으로 나누어서 관리 힌다. |
Distributed Systems | Broken Patterns | use in distributed application |
Interactive Systems | Model-View-Controlled, Presentation-Abstraction-Control Pattern | - |
Adaptable Systems | Microkernel pattern | - |
2.2.1. Layers ¶
- 예제(Example) : 이 패턴은 우리가 주위에서 흔히 많이 볼 수 있는 패턴이다. TCP/IP가 그 대표적인 예일 것이다.
- 환경(Context) : 분해가 필요한 큰 시스템
- 생각 해야할 문제(Problem - balance in following forces)
- 최근에 수정되는 소스는 그것이 속한 component에만 영향을 주어야지 다른 component에까지 영향을 끼쳐서는 안된다.
- interface는 안정적이어야 한다.
- 시스템의 각 부분은 교환 가능해야 한다. (Design for change in general is a major facilitator of graceful system evolution - 일반적으로 변화에 대비한 디자인을 하는것은 우아한 시스템 개발의 주요한 촉진자이다.)
- It may be necessary to build other systems at a later date with the same low-level issues as the system you are currently designing ( 정확한 의미는 모르겠음, 누가 해석좀....)
- 이해하기 쉽고 유지보수도 하기 쉽게 하기 위해서 유사한 필요한 기능(responsibilities)을 그룹화 한다.
- 기준이 되는 component 모양은 없다.
- component 경계가 교차 하는것은 성능의 저하를 초래한다. 예를 들어 많은 양의 데이터가 레이어를 지날때 또한 역시 많은 교차하는 component 경계를 지나게 되기 때문이다.
- 이렇게 레이어로 깨끗이 나누어서 프로그램을 짜면 팀으로 작업을 할때 좀더 능률적이다.
- 최근에 수정되는 소스는 그것이 속한 component에만 영향을 주어야지 다른 component에까지 영향을 끼쳐서는 안된다.
- 해결책(Solution) : 자신의 시스템을 적당한 숫자의 레이어로 나누고 각 레이어를 알맞는 순서에 맞게 쌓는다
- 구조(Structure) : 레이어는 다음과 같은 기본 구조를 가지고 있다.
- Class : 레이어 J
- 해야할 기능(responsibility)
- 레이어 J+1에 의해서 사용될 서비스를 제공한다.
- 하부 작업을 레이어 J-1에게 넘긴다.(위임한다)
- 레이어 J+1에 의해서 사용될 서비스를 제공한다.
- 협력자(collaborator) : 레이어 J-1
- 레이어 패턴의 중요한 구조적인 특징은 레이어 J는 오직 레이어 J+1에 의해서만 사용될 수 있다는 점이다. (스택이나 양파와 비교할 수 있다)
- Class : 레이어 J
- Dynamics
- Scenario1 - top-down communication, 가장 잘 알려진것이다. 클라이언트가 레이어 N에게 요청을 한다. 그러면 레이어 N은 홀로 모든 작업을 할 수 없기 때문에 하부 작업을 레이어 N-1에게 넘긴다. 그러면 레이어 N-1은 자신의 일을 하고 레이어 N-2에게 하부 작업을 넘기고, 이런식의 과정이 레이어 1에 도달할때까지 이루어 진다. 그래서 가장 낮은 수준의 서비스가 수행된다. 만약 필요하다면 다양한 요청에 대한 응답들이 레이어 1에서 레이어 2, 이런식으로 레이어 N에 도달할때까지 이루어진다. 이러한 top-down 소통의 특징은 레이어 J는 종종 레이어 J+1로부터 온 하나의 요청을 여러개의 요청으로 바꿔서 레이서 J-1에게 전한다. 이는 레이어 J가 레이어 J-1보다 더 추상적이기 때문이다. 덜 추상적인것이 여러개 모여서 더 추상적인것이 되는 것을 생각해보면 이해가 갈것이다.(예를 들어 복잡한 소켓 프로그래밍을 자바에서는 간단한 명령어로 금방 한다.)
- Scenario2 - bottom-up communication, 레이어 1에서 시작하는 연쇄적인 동작들이다. top-down communicatin과 헷갈릴 수도 있는데 top-down communication은 요청(requests)에 의해서 동작하지만, bottom-up communication은 통지(notifications)에 의해서 동작한다. 예를 들어서 우리가 키보드 자판을 치면, 레벨1 키보드에서 최상위 레벨 N에 입력을 받았다고 통지를 한다. bottom-up communicatin에서는 top-down communication과는 반대로 여러개의 bottom-up 통지들(notifications)은 하나의 통지로 압축되어서 상위 레이어로 전달되거나 그대로 전달된다.
- Scenario3 - 레이어 N-1이 cache로 작용하여서, 레이어 N의 요청이 레이어 N-1에게만 전달되고 더이상 하위 레이어로 전달되지 않는다. 요청을 보내기만 하는 레이어들이 상태가 없는(stateless) 반면에 이러한 cache 레이어는 상태 정보를 유지한다. 상태가 없는 레이어들은 프로그램을 간단하게 한다는 이점이 있다.
- Scenario4 - 레이어 1에서 event가 감지되었지만 레이어 3까지만 가고 더이상 가지 않는 경우와 같은 경우, 예를 들어서 성격 급한 클라이언트가 데이터를 요청하고, 못 기다리고 금방 다시 요청하는 경우에 첫번째 요청으로 응답 데이터가 가다가 두번째 요청이 오는것과 교차하게 된다. 이때 두번째 요청도 첫번째 요청과 같은 것이기에 이때 이 요청이 도이상 가지 않게 한다.
- Scenario 5 - N개의 레이어들로 이루어진 2개의 stack 들이 서로 소통 하는 경우이다. 통신 프로토콜이 대표적인 예이다. 한쪽의 레이어 N에서 보내는 요청은 결국 하위 레이어 1(하드웨어 레벨)을 통해서 상대편 하위 레이어1로 전해지고, 이것은 또 N 레이어로 쭉 올라간다.
- Scenario1 - top-down communication, 가장 잘 알려진것이다. 클라이언트가 레이어 N에게 요청을 한다. 그러면 레이어 N은 홀로 모든 작업을 할 수 없기 때문에 하부 작업을 레이어 N-1에게 넘긴다. 그러면 레이어 N-1은 자신의 일을 하고 레이어 N-2에게 하부 작업을 넘기고, 이런식의 과정이 레이어 1에 도달할때까지 이루어 진다. 그래서 가장 낮은 수준의 서비스가 수행된다. 만약 필요하다면 다양한 요청에 대한 응답들이 레이어 1에서 레이어 2, 이런식으로 레이어 N에 도달할때까지 이루어진다. 이러한 top-down 소통의 특징은 레이어 J는 종종 레이어 J+1로부터 온 하나의 요청을 여러개의 요청으로 바꿔서 레이서 J-1에게 전한다. 이는 레이어 J가 레이어 J-1보다 더 추상적이기 때문이다. 덜 추상적인것이 여러개 모여서 더 추상적인것이 되는 것을 생각해보면 이해가 갈것이다.(예를 들어 복잡한 소켓 프로그래밍을 자바에서는 간단한 명령어로 금방 한다.)
- 실행(implementation) - 아래 과정은 모든 application에 반드시 가장 좋은 방법이라고 할 수는 없다. 종종 bottom-up이나 yo-yo 방법으로 접근하는것이 더 좋을지도 모른다. 자신의 application에 필요하다 싶은 과정을 짚어서 하면 된다.
- task(과업,일) 들을 레이어에 배치하기 위한 추상적인 기준을 정의 하여라. 실제적인 소프트웨어 개발에서 우리는 종종 추상적인 기준들의 혼합을 사용한다. 예를들어서 하드웨어적인 관점에서 저 수준의 레벨들의 모습을 정하고, 개념적인 복잡성으로 고 수준의 레벨을 정한다.
- 당산의 추상적인 기준에 따라서 추상 레벨들의 갯수를 정하여라. trade-off를 생각해보면서 레이어를 통합하거나 분리해라. 너무 많은 레이어는 프로그램에 과중한 부담이 되고, 너무 적은 레이어는 구조적으로 좋지 않게 된다.
- 레이어들의 이름을 정하고 각 레이어에 tasks(과업)을 정해 주어라. 모든 레이어의 tasks는 자신 보다 높은 레이어를 도와야 한다.
- services 들을 명확히 하여라. 가장 중요한 구현 원칙은 레이어들이 엄격하게 각자 분리 되어야 한다는 점이다. 레이어들 사이에 공유되는 모듈은 엄격한 layering 약하게 한다. 그리고 낮은 레이어보다 높은 레이어에 더 많은 service를 넣는것이 더 낮다.
- Refine layering. 위의 1~4번 과정을 반복 하여라.
- task(과업,일) 들을 레이어에 배치하기 위한 추상적인 기준을 정의 하여라. 실제적인 소프트웨어 개발에서 우리는 종종 추상적인 기준들의 혼합을 사용한다. 예를들어서 하드웨어적인 관점에서 저 수준의 레벨들의 모습을 정하고, 개념적인 복잡성으로 고 수준의 레벨을 정한다.
~cpp 컴포넌트나 서비스가 사용되는 관계 | 레이어들 |=> 이것들을 생각 하고나서 define components and service 레이어들의 서비스 | 이 순서가 바뀌는 것은 잘못된 과정이다.
- 각 레이어에 대한 인터페이스를 명확히 해라 (가능한한 black-box 접근을 사용하는 것이 좋다, 이것이 시스템 발전을 도와주기 때문이다. 효율이나 다른 레이어의 내부에 접근할 필요가 있을때는 예외이다.)
- 각 레이어를 체계화 하여라. 어떤 레이어가 복잡하면 component들로 나누어 져야 한다.
- 인접한 레이어들 사이의 소통을 명확히 하여라.
- Decouple adjacent layers
- 변형(variants)
- Relaxed Layered System : 이시스템을 통해서 얻은 유연성과 성능의 향상은 유지보수 능력의 저하를 가져온다. application 소프트웨어 보다 infrastructure(영구적인) 시스템에서 자주 본다. UNIX, X Window System가 그예이다.
- Layering Through Inheritance : 상속 관계로 레이어 패턴을 구현. 현재 뜨는 OOP로 할 수 있다.
- Relaxed Layered System : 이시스템을 통해서 얻은 유연성과 성능의 향상은 유지보수 능력의 저하를 가져온다. application 소프트웨어 보다 infrastructure(영구적인) 시스템에서 자주 본다. UNIX, X Window System가 그예이다.
- 이 패턴의 알려진 사용예 (Known Uses)
- Virtual Muchines
- APIs
- Information System(IS)
- Windows NT
- Virtual Muchines
- 결론
- 장점
- 레이어의 재활용 - 프로그래머들은 현재 존재하는 레이어가 자신의 목적에 맞지 낳는다고 이미 있는것을 재사용 하기보다는 새로 짜는 경우가 많다. 그러나 현재 존재하는 레이어를 재사용(black-box reuse)하는 것은 개발에 드는 노력과 프로그램의 결점들을 극적으로 감소 시킬 수 있다.
- 기준을 지원한다.
- Dependescies are kept local : 의존성이 특정 부분에만 걸쳐 있기 때문에 이렇게 된다. 따라서 시스템이 portability하게 된다.
- Exchangeability : 특정 레이어를 쉽게 바꿀 수 있다. 그것을 바꿔도 전체적으로 다른 부분은 안바꿔도 된다. 바꾸는 것은 당연히 그 바꿀 대상 레이어의 인터페이스데로 구현되어 있는 것이어야 한다.
- 레이어의 재활용 - 프로그래머들은 현재 존재하는 레이어가 자신의 목적에 맞지 낳는다고 이미 있는것을 재사용 하기보다는 새로 짜는 경우가 많다. 그러나 현재 존재하는 레이어를 재사용(black-box reuse)하는 것은 개발에 드는 노력과 프로그램의 결점들을 극적으로 감소 시킬 수 있다.
- 불리한 점(liability)
- cascades of changing behavior : 레이어를 바꾸는것뿐만 아니라 그 인터페이스를 바꿀경우에 다른 부분까지 수정해줘야 한다는 말 같다.
- lower efficiency : 여러개의 레이어를 지나야 하니깐 시간이 더 걸리는 것은 당연할 일이다.
- Unnecessary work : 필요없는 일도 하는 경우가 있다.
- 레이어를 정확히 구축하는것이 어려운 일이다.
- cascades of changing behavior : 레이어를 바꾸는것뿐만 아니라 그 인터페이스를 바꿀경우에 다른 부분까지 수정해줘야 한다는 말 같다.
- 장점
- 의견 : 이 layer 패턴을 사회적인 것과 결부시켜서 생각하면 관료제와 비슷하다고 생각한다. 교체 가능하고, 단계적으로 올라가고, 내려가고 뭐 여러가지 점이 유사하다. 이 패턴이 사용하는 사람들이 관료제에서 착안해서 이 패턴을 사용하는 것은 아니겠지만 하여튼 그러한 유사점을 발견하니깐 신기했다.
2.2.2. Pipes and Filters ¶
- 예제 : 여기서는 프로그래밍 언어를 예로 들어서 설명했다.
- 환경 : 데이터 흐름의 처리
- 생각해야할 문제
- 추후의 시스템 향상이 사용자에 의해서 조차, 처리 단계(step)들을 바꾸거나 재조합 하는것으로서 가능해야 한다.
- 작은 처리 단계가 큰 components 보다 다양한 환경에 재사용 하기 좋다.
- 인접하지 않은 단계는 정보를 공유하지 않는다.
- 예를 들어서 네트워크 연결이나 온도 정보를 제공하는 센서와 같이 다양한 입력 데이타 source 가 존재한다.
- 최종 결과를 다양한 방법으로 저장하거나 나타내는 것이 가능해야 한다.
- 등 여러가지..
- 추후의 시스템 향상이 사용자에 의해서 조차, 처리 단계(step)들을 바꾸거나 재조합 하는것으로서 가능해야 한다.
- 이 패턴은 : data source - filter - pipes - filter - data sink, 의 순서로 되어 있고, 각 필터에서는 데이터를 처리하는 함수가 있을 수 있다. 레이어 패턴과 비슷한 점도 보이지만, 이 패턴의 특징은 쉬운 재조합과 재사용성이다. 에러를 처리하는 관점과 시스템의 신뢰성을 따지면 레이어가 더 낮다.
- 의견 : 이 패턴은 우체국과 비슷해 보였다. ㅡㅡ;,
2.2.3. BlackBoard ¶
- 예제 : 여기서는 음성인식 시스템을 예로 들었다. 음성인식 프로그램은 단지 하나의 단어를 받아들일 뿐만 아니라 구문과 단어가 특정한 application에 필요한 단어나 구문론에 맞는 것으로 제한된 문장 전체를 받아 들인다. 원하는 output은 그 음성 인식한것에 맞는 기계적인 표현으로 바꾸는 것인데 이 변환 과정에는 음성을 음파적으로 인식하는 것과, 언어학적인 면에서 인식하는것과, 통계적인 전문성에서 인식하는 것이 필요하다.
- 환경 : 적당한 solution이 아직 없는 성숙하지 않은 영역
- 생각해야할 문제 : 각각의 문제에 대한 해결책은 다른 표현이나 paradigms 이 필요하다. 많은 경우에 어떻게 '부분적인 문제들을 풀어주는 해결책'이 어떻게 조합되어야 하는지에 대해서 미리 정의된 전략은 없다. 아래의 내용은 이런 종류의 문제를 푸는데 영향을 끼지치는 force(이 패턴이 사용되는 경우?)들이다.
- 적당한 시간에 완전한 해결책을 찾는 것이 불가능 하다 - 10개의 단어(1000개중 하나)를 조합하여 가능한 구문의 수=>(1000)의 10승 과 같은 예
- 그 영역이 미성숙해서, 같은 하부 task에 여러가지 알고리즘을 사용한다.
- 각 부분의 문제를 풀때 다양한 알고리즘이 존재한다.
- input은 intermediate 와 마지막 result와 마찬가지로 다양한 표현이 있다. 알고리즘들은 다양한 paradigm들에 의해서 수행된다.
- 하나의 알고리즘은 보통 다른 알고리즘의 결과 위에서 작동한다.
- 부정확한 데이터와 근사적인 해결책(solution)들이 포함된다.
- 각각 분리된 알고리즘을 채용하는 채용하는 것은 잠재적인 평형 관계를 유도한다.
- 모든 부분적인 문제들은 같은 knowledge 표현을 사용하여 해결된다. 그러나 input으로 다양한 표현이 올 수 있다.
- 전문적인 시스템 구조는 application of knowledge에 대해서 단지 하나의 추론 엔진을 제공한다. 다양한 표현에 대한 다양한 부분적인 문제들은 분리된 추론 엔진을 필요로 한다.
- -
- 적당한 시간에 완전한 해결책을 찾는 것이 불가능 하다 - 10개의 단어(1000개중 하나)를 조합하여 가능한 구문의 수=>(1000)의 10승 과 같은 예
- 해결책(solution) : Blackboard 구조의 바탕에 깔린 개념은 공동의 데이터 구조에 대해서 협동적으로 작동하는 독립된 프로그램들의 집합이다. 그 독립적인 프로그램들은 서로 다른 프로그램을 호출하지 않고 또한 그것의 행동에 대해 미리 정의된 순서는 없다. 대신에 시스템의 방향은 주로 현재의 상태나 진행(progress)에 의해 결정된다. 데이터-관리 조종 체계(data-directed control regime)는 opportunistic problem solving 이라고도 불린다. moderator(중재자) component는 만약 하나 이상의 component가 contribution을 만들수 있다면 프로그램들이 실행되는 순서를 결정한다.
- 구조 : 자신의 시스템을 blackboard(knowledge source들의 집합, control components)라고 불리우는 component로 나누어라. blackboard는 중앙 데이터 저장소이다. solution space와 control data들의 요소들이 여기에 저장된다. 하나의 hypothesis는 보통 여러가지 성질이 있다. 그 성질로는 추상 레벨과 추측되는 가설의 사실 정도 또는 그 가설의 시간 간격(걸리는 시간을 말하는거 같다.)이다. 'part-of'또는'in-support of'와 같이 가설들 사이의 관계를 명확이 하는 것은 보통 유용하다. blackboard 는 3차원 문제 공간으로 볼 수도 있다. X축 - time, Y축 - abstraction, Z축 - alternative solution. knowledge source들은 직접적으로 소통을 하지 않는다. 그들은 단지 blackboard에서 읽고 쓸뿐이다. 그러므로 knowledge source 들은 blackboard 의 vocabulary들을 이해해야 한다. 각 knowledge source들은 condition부분과 action부분으로 나눌 수 있다. condition 부분은 knowledge source가 기여를 할수 있는지 결정하기 위해서 blackboard에 적으면서 현재 solution process 의 상태를 계산한다. action 부분은 blackboard의 내용을 바꿀 수 있는 변화를 일으킨다. control component 는 루프를 돌면서 blackboard에 나타나는 변화를 관찰하고 다음에 어떤 action을 취할지 결정한다. blackboard component는 inspect와 update의 두가지 procedure를 가지고 있다.
~cpp Class : BlackBoard Responsibility : Manages central data Collaborators : - Class : Knowledge Source Responsibility : Evaluates its own applicability, Computes a result, Updates Black board Collaborators : Blackboard Class : Control Responsibility : Monitors Blackboard, Schedules Knowledge Source activations Collaborator : Blackboard, Knowledge Source
- Dynamices(동작)
- 다음 아래의 내용들은 blackboard 구조의 행동에 대한 서술이다.
- control component의 main loof가 시작된다.
- nextSource() 먼저 blackboard를 관찰함으로써 어떤 knowledge source가 잠재성있는 공헌자인지 결정한다.
- nextSource() 각 후보 knowledge source의 condition 부분을 불러낸다.
- control component는 불러낼 knowledge source와 앞으로의 작업에 사용될 하나의 hypothesis나 hypothesis 집합을 선택한다. 예제에서는 condition 부분의 결과에 의해서 그 선택이 이루어졌다.
- control component의 main loof가 시작된다.
- 다음 아래의 내용들은 blackboard 구조의 행동에 대한 서술이다.
- 구현(implementation) : blackboard pattern을 구현하려면 다음과 같은 단계를 수행하여라.
- 1.문제(problem)를 정의 하여라
- 문제의 영역과 knowledge의 일반적인 영역들을 명확히 하는 것은 해결책(solution)을 발견하는데 필요하다.
- 시스템에 대한 input을 정밀하게 조사하여라.
- 시스템의 output을 정의하여라
- 사용자가 시스템과 어떻게 서로 작용하는지 자세히 말하여라.
- 문제의 영역과 knowledge의 일반적인 영역들을 명확히 하는 것은 해결책(solution)을 발견하는데 필요하다.
- 2.그 문제에 대한 solution space(해결 공간)을 정의하여라.
- 1.문제(problem)를 정의 하여라
~cpp top-level solution - highest abstraction level imtermediate solution - other level(except highest abstraction level) complete solution - solution which solve whole problem partial solution - solution which solve part of the problem complete solution은 intermediate 레벨에 속할수 있고, partial solution은 아마도 top 레벨일 것이다.(무슨말이지?ㅡㅡ;)