GoF 디자인 패턴
1. GoF 디자인 패턴 종류
구분 |
종류 |
생성 패턴 |
Singleton, Abstract Factory, Factory Method, Builder, Prototype |
구조 패턴 |
Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy |
행위 패턴 |
Command, Interpreter, Iterator, Mediator, Template Method, Visitor, State, Strategy, Observer, Chain of Responsibility, Memento |
2. 생성 패턴
- 객체를 생성하고 참조하는 과정을 추상화하여 시스템이 객체의 생성과 조합들에 구애 받지 않고 개발될 수 있도록 도와준다.
- 특정객체가 생성되고 변경되어도 전체 시스템의 변화는 최소화가 되도록 만들어 주어, 시스템의 확장이나 유지보수 시 최소 비용만 소요된다.
(1) Sigleton
- 객체를 하나만 생성해서 이용하는 패턴
- 어떤 클래스의 인스턴스는 오직 하나임을 보장함
- Singleton s = new Singleton();
- Singleton s = Singlton.getInstance(); (Private 생성자를 이용해 강제한다)
(2) Factory Method
- Factory Method 패턴과 Abstract Factory 패턴의 기본이 되는 패턴
- Factory 패턴의 기본 모양에서 객체 생성을 Factory 클래스의 하위 클래스에서 처리하도록 하는 패턴
- 생성하려는 객체의 클래스를 정확히 지정하지 않으면서 객체를 만드는 또 다른 메소드를 정의하여 처리
- 추상메소드 getConnection()을 가진다.
- 하위 자식 클래스 TCPCOnnectionFactory, UDPConnectionFactory, HTTPConnection Factory에서 getConnection() 메소드를 각각에 알맞게 구현한다.
(3) Abstract Factory
- Factory 클래스를 추상으로 제공
- Factory Method 패턴이 공장라인의 부품을 교체할 때 유용한 것이라면 Abstract Factory 패턴은 공장라인 자체를 교체하는 것에 유용하다.
- 다양한 구성 요소 별로 객체의 집합을 생성해야 할 때 유용하다.
- 예)
Robot homeRobot = new Robot();
RobotFactory homeFactory = new HomeRobotFactory();
homeRobot.addHead(homeFactory.createHead());
.
.
homeRobot.displayRobot(); // 전체 로봇을 출력한다.
(4) Builder
- 객체 생성 작업을 대신해줄 클래스를 추가하는 패턴
- 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴
- 객체 생성이 복잡하거나 여러 개의 추가 작업이 필요한 경우 유용함
- 예)
Director director = new Director(new HTMLBuilder(), "member.html");
director.construct();
director.makeFile();
(5) Prototype
- 복제 패턴, clone() 메소드 이용
- 생성할 객체들의 타입이 프로토타입인 인스턴스로부터 결정되는 패턴
- 프로토타입인 인스턴스는 새로운 객체를 만들기 위해 클론(clone) 됨
- 주의
① : Object의 done() 메소드는 protected로, 상속 후 재정의가 필요함
② : Cloneable 인터페이스 구현이 필요함 (그렇지 않으면 CloneNotSupportedException 발생)
3. 구조 패턴
- 복잡한 구조를 이루는 클래스들을 어떻게 개발하기에도 쉽고 보기에도 좋은 형태를 만들 것인가에 대한 답을 제시
- 구조 패턴을 이용해서 시스템을 구축하면 새로운 기능을 가진 복합객체를 효과적으로 작성할 수 있다.
(1) Adapter
- 위임을 이용한 방식
> Book은 Arraylist에 담는 것이 좋을까, BookStore에 담는 것이 좋을까?
- 상속을 이용한 방식 (주의)
① 이미 다른 클래스를 상속 받았다면 사용할 수 없다.
② LSP에 따라 분명히 상속 관계인 경우에만 사용해야 한다.
③ 상속이 강한 결합의 형태로 잘못 작성된 경우 수정이 불가능한 상황이 발생할 수 있다.
(예 : Vector 클래스를 상속 받은 Stack 클래스)
(2) Bridge
- 구현부에서 추상층을 분리하여 각자 독립적으로 변형할 수 있게 하는 패턴
- 기능 클래스 계층과 구현 클래스 계층을 연결하는 다리
- 기능 클래스 계층 : MultiWrite에 print(int) 기능이 추가되었다.
- 구현 클래스 계층 : FileWriteImpl 을 통해 구현되었다.
- 예)
MultiWriter mw = new MultiWriter(new FileWriteImpl("test.txt", "test success");
(3) Composite
- 객체들의 관계를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴(복합패턴)
- 재귀적 구조, 파일디렉토리 탐색기 구조
- 예)
Department d1 = new Department("전체부서");
Department d2 = new Department("개발부");
d1.add(d2);
Employee e1 = new Employee("김주혁");
Employee e2 = new Employee("김고흔");
d2.add(e1);
d2.add(e2);
d1.print(); // 한 번에 전체보기
(4) Decorator
- 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴
- 장식대상이 되는 클래스와 장식 클래스를 구분해야 함.
- 예)
StarWindow sw = new StarWindow(10.5);
sw.draw();
VerticalSharpWindow hsw = new VerticalSharpWindow(sw);
hsw.draw(); // 장식 대상(sw), 장식 (hsw)
- 예2)
BifferedReader br = new BifferedReader(new InputStream Reader(System.in));
(5) Facade
- 클래스 라이브러리 같은 어떤 SW의 다른 커다란 코드 부분에 대한 간략화 된 인터페이스를 제공하는 객체 이용 패턴
- 높은 레벨의 간략한 인터페이스 제공
- 예)
UseFileMaker maker = new UseFileMaker();
maker.makeUseFile("usefile.txt");
UseFileMaker 클래스의 makeUsefile 메소드만 호출하여 전체 업무를 처리한다.
(6) Flyweight
- 가능한 많은 데이터를 서로 공유하여 사용하도록 하여 메모리 사용량을 최소화하는 패턴
- 가능한 new를 통한 객체 생성을 줄여 메모리를 적게 차지하고 객체를 메모리에 올리기 위한 오버헤드를 줄인다.
(7) Proxy
- 본인 객체 대신 대리인 객체가 어느 정도 일을 처리해 주는 대리인 패턴
- AddressBookProxy가 작업을 가져가고 일부 FileLoader를 이용하는 작업만 AddressBookImpl이 수행한다.
- 예)
AddressBookProxy proxy = new AddressBookProxy("data.ser");
proxy.add(new AddressImpl("Apple inc.", "1Infinite Loop", "Redwood City", "CA", "93741"));
ArrayList addresses = proxy.getAllAddresses();
3. 행위 패턴
- 객체들간에 행위나 알고리즘 등과 관련된 패턴
- 응용 분야에 따라 행위가 다른 객체로 옮겨가거나 알고리즘이 대체되는 경우에 많은 도움을 주는 패턴이다.
(1) Command
- 메소드 호출을 명령으로 생각하고 명령을 모아서 관리하는 명령 패턴
- 명령의 집합을 보존해두면 똑같은 명령을 재실행할 수 있고, 여러 개의 명령을 모은 것을 새로운 명령으로 재사용할 수 있다.
- 요청을 객체의 형태로 캡슐화하여 서로 요청이 다른 사용자의 매개변수와 요청 저장 또는 로깅, 그리고 연산의 취소를 지원하게 만든다.
(2) Iterator
- 몇 개인지 몰라도 무엇인가 많이 모여있는 것 중에서 하나씩 끄집어 내어 열거하면서 전체를 검색하는 반복 패턴
- 일반적으로 hasNext() 메소드를 통해 다음이 존재하는지 확인하고 next() 메소드를 통해 다음 항목을 하나씩 끄집어 낼 수 있다.
- JDK 1.2 버전부터 추가된 Collection Framework 자료구조는 Iterator 패턴 사용
(3) Mediator
- 각 클래스가 분산되어 있는 경우 조정자 혹은 중개자를 두어 처리의 효율성을 높일 수 있는 중재자 패턴
- 예)
Mediator 가 BtnView, BtnSearch, BtnBook 클래스를 중재한다.
Mediator 클래스는 각 멤버들과 Association 관계에 있다.
(4) Template Method
- 상위 클래스에 템플릿을 정해 놓고 하위 클래스에서 구체적인 내용을 결정하는 패턴
- 템플릿을 만들어 프로세스를 강조하고 싶은 경우 사용한다.
- 프로세스를 강제하는 메소드를 템플릿메소드라고 부른다.
- 예) Check 프로세스를 아래와 같이 정의함
public void check(){
checkBank();
checkCredit();
checkLoan();
checkStock();
checkIncome();
}
(5) Visitor
- 방문자 패턴
- 데이터 구조와 처리를 분리하여 데이터 구조 안을 돌아다니는 방문자 클래스에게 처리를 맡기는 패턴
- 새로운 처리 기능이 필요한 경우 해당 방문자를 만든다.
- 예)
public void accept(Vistor v){
v.visit(this);
}
(6) State
- 객체가 아닌 상태를 클래스로 표현하는 상태 패턴
- Accounting 상태, Sales 상태, Management 상태, 각 상태별로 open/close/log 메소드가 다르게 동작한다.
(7) Strategy
- 알고리즘으로 구현될 부분을 교체 가능하도록 처리하는 전략패턴, 알고리즘 패턴
- 시스템 속에 다양한 전술(알고리즘)이 동일한 객체 속에 존재하도록 만들고 상황에 따라 필요한 전술이 사용되도록 한다.
- 예)
컴퓨터와 바둑 게임 시 초보자/중수/고수라는 전략 알고리즘을 구현한 객체를 따로 만들어 놓고, 상황에 따라 다르게 실행할 수 있다.
(8) Observer
- 관찰 대상의 상태가 변경되면 관찰자에게 통지되는 관찰자 패턴
- 실제적으로 관찰 대상으로부터 변화가 생기면 통지를 기다리는 역할을 수행 (publish-subscribe : 발행-구독)
- 특정 데이터나 객체를 감시하고 있다가 변화가 발생 했을 때, 시스템에 이를 알리고 연관된 객체들이 적절한 작업을 동일한 인터페이스를 이용하여 실행하도록 만든다.
- 예)
JDK에서 java.util.Observer / java.util.Observable 두 가지를 제공하지만 이미 다른 클래스를 상속 받고 있을 경우, 하위 클래스로 만들기 어렵기 때문에 직접 Observer 패턴을 구현하는 것이 좋음
(8) Chain of Responsibility
- 각자 객체가 자신이 맡은 책임을 완수하여 전체적인 요구를 수용할 수 있게 하는 책임연쇄 패턴
- 사용자가 원하는 작업을 어떤 객체에게 시킬지 모를 때, 그냥 작업을 객체들의 집합에 던져 버리면 되도록 만드는 패턴
- 예)
Manager : 10 * Base
Director : 20 * Base
VicePresident : 40 * Base
President : 60 * Base
Manager가 감당할 수 없는 일인 경우 Director에게 넘긴다.
(9) Memento
- 이전 행위를 Memento 클래스의 객체로 생성하여 undo list에 보존하는 보존과 복원 패턴
- 시스템이 이전에 수행했던 작업을 기억하고 이전의 작업으로 복귀를 해야 하는 구조를 가져야 할 때 유용하게 사용할 수 있는 패턴
- Memento 패턴을 이용하면 Undo, Redo, Snapshot 등을 실행할 수 있다.
- 예)
undo List에 등록한다.
previous() 메소드를 통해 이전 정보를 찾을 수 있다.
(10) Interpreter
- 인터프리팅을 위한 패턴
- 새로운 스크립트 언어를 위한 패턴으로 엑셀 스크립트를 통해 엑셀의 변경 없이 엑셀에 새로운 기능을 수행 할 수 있다.
- 예) 간단한 미니 언어 작성하기 (EBNF 표기법)
<command List> ::=<comand>*end
<command> ::=<repeat comman> | <primitive comman>
<primitive command> ::= go | right | left
<program> ::= repeat<number><command list>
'Application' 카테고리의 다른 글
What are the differences between PEM, DER, P7B/PKCS#7, PFX/PKCS#12 certificates (0) | 2015.08.31 |
---|---|
파일 시그니처 모음 (Common File Signatures) (0) | 2015.07.02 |
Penetration Test System (0) | 2014.10.25 |
[Wireless Security] 무선 네트워크 암호화 WEP(Wired Equivalent Privacy) (0) | 2014.10.25 |
logic gate (AND, OR, XOR, NOT, NAND, NOR, and XNOR) (0) | 2014.10.25 |