Niceit.tistory.com GoF 디자인패턴 온달의 IT 세상 REVIEW 재사용및품질향상을위한위한 GoF 디자인패턴 핵심키워드 - 디자인패턴유형. 생성패턴 / 구조패턴 / 행위패턴. 재사용성 / 모듈성 / 생산성극대화 REVIEW 목차 I. GoF의디자인패턴의개요 II. GoF의디자인패턴의유형 III. GoF의디자인패턴세부설명 IV. 디자인패턴의유용성 작성자 : 이덕우페이지 1 / 11
I. GoF 디자인패턴 의개요 I. GoF 디자인패턴의개요 가. 개념 소프트웨어개발시자주발생되는문제해결을위한솔루션 ( 재사용 ) 특정상황에서일반적설계문제해결을위해상호교류하는수정가능한객체와클래스들에대한설명 객체지향언어에디자인패턴을접목한 Erich Gamma, Richard Helm, Ralph Johnson, Jone Vlissides 등네사람을존경하기위해 GoF(Gang of Four) 애칭붙여사용 나. 시스템구축시디자인패턴적용의장점 이미검증된솔루션재사용 품질보증 / 생산성향상 이해관계자들간의공통언어역할과코드의품질향상 향후변화에대비한유지보수용이성증대 II. GoF 의디자인 패턴의유형 II. GoF 디자인패턴의유형 가. 생성패턴 : 객체생성할때사용되는여러방법들 객체를생성하고참조하는과정을추상화하여시스템이객체의생성과조합등에구애받지않고개발 특정개체가생성되고변경되어도전체시스템의변화는최소화 시스템의확장이나유지보수시비용최소화 Factory Method, Abstract Factory, Builder, Prototype, Singleton 나. 구조패턴 : 클래스가다른클래스를통해구조적으로어떤관계를맺을수있는지보여줌 복잡한구조를이루는클래스들을어떻게하면개발하기에쉽고보기에도좋은형태를만들어줄것인가에대한해답제시 새로운기능을가진복합객체를효과적으로작성 Facade, Adapter, Bridge, Composite, Decorator, Flyweight, Proxy 다. 행위패턴 : 클래스들간서로어떻게협력하여작업을수행하는지에대한해답제시 객체들간의행위나알고리즘등과관련된패턴 응용분야에따라행위가다른객체로옮겨가거나알고리즘이대체되는경우가존재하기마련인데, 이때많은도움을주는패턴 Memento, Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Observer, State, Strategy, Template Method, Visitor III. GoF 의디자인 패턴세부설명 III. GoF 의디자인패턴세부설명 가. 생성패턴 작성자 : 이덕우페이지 2 / 11
III. GoF 의디자인 패턴세부설명 여러개의객체의집합을포함하고있는어플리케이션을설계하는데유용함패턴설계목적사례요약 팩토리 런타임시에객체가결정되 단일제어코드로 Factory 어야 하는 경우 Base 여러다양한고객에 Class를이용하여동적생성 게차별된메일메시지발송 추상팩토리 런타임에협력하는객체들 런타임에사용자가 Abstract 의패밀리를스타일선택 스타일을선택하여 Factory 에의하여생성 키친레이아웃디스 플레이 프로토타입 - 클래스를 인스턴트로 사용자가런타임에 Prototype 만들어놓고필요할 붙박이장과바닥장 때마다생성하지않고 의유형을선택할 복사해서사용 수있고이를디스 - 선택한부품의복사본 플레이 으로이루어지는객체 의생성집합 싱글톤 오직하나의객체만을생 객체가오직하나이 Singleton 성하는클래스 며응용에서이를 접근 객체를리턴하는메소드를이용하여필요객체생성스타일에맞는객체를리턴하는메소드를객체가갖도록함 - 프로토타입의클론을만들어타입객체를생성 - 클론메소드 - 필요시프로토타입의클론생성생성자를 Private, Public static메소드가유일한객체를취할수있도록함. 나. 구조패턴 객체모음을트리나링크리스트형태로정리하는데도움 패턴 설계목적 사례 요약 어뎁터 Adapter 어플외부의기능을사용가능케함 대출에관한응용을설계시매달값아야할금액을계산하는외부에서개발된클래스를사용하는경우 중간조정클래스에어플을링크하여필요한기능을갖도록함 파사드 대규모클래스를포함 부문별 전담토록하여 각패키지에대하 Façade 하는소프트웨어아키 상호협력문제최소화 여싱글톤객체를 텍처관리 - 대출조건 DB 만들어이를접근 - 서브시스템의내부 - 사용자인터페이스 하게함 가복잡하여클라이언트코드가사용하기힘들경우사용 ( 간단한출입 - 계산로직 작성자 : 이덕우페이지 3 / 11
III. GoF 의디자인 구 ) 패턴세부설명 프록시 - 일부메소드가실 이미지랜더링을위하 요청한 메소드와 Proxy 행될때많은자원 여많은시간과공간을 자원사이에존재 ( 시간, 공간 ) 이필요 소모하는경우파일에 하는클래스소개 하며리모트로동 서이미지를읽고버퍼 작하게함 애채워랜더링하여야 - 자주실행될필요 하기때문 가없는것 다. 행위패턴 객체사이의행위, 즉작용과반응을모아놓은것 패턴설계목적사례요약 옵서버 Observer 중재자 Mediator 커맨드 Command 비지터 Visitor 여러객체가한객체에의 존하여이것이변경될때 영향을받아작업을수행 하는것 서로지칭하지않고객체 사이의인터액션을모아 중재 동적목적 : 클라이언트 코드에게객체들에분산된 기능을사용하게함 대규모클래스를포함하는 아키텍처를관리 계층구조의클래스들을변 경하지않고새로운오퍼 레이션을정의 관리, 마케팅, 영업팀 에서오늘까지의 영업실적을알아보 기위해다른작업 이바뀔때마다 Update() 호출 배가항구에입항하 고출항하는데걸리 는시간추정문제에 서 Ship 과 Tugboat 클래스는별도로사 용할수있게독립 적으로만듦 이미수행한 4 개의 결정을언제든지취 소하게함 (Undo) 구문트리에있는 각노드를방문하는 비지터객체를만들 때사용 관찰대상클래스 에옵서버객체를 연결해두고값이 바뀔때마다 Update 호출 관련된객체가모 인클래스들의인 터랙션을뽑아냄 커맨드타입을자 기클래스안에 보존 구체적으로 노드 를방문하는비지 터타입을계층 구조로형성 IV. 디자인패턴의 유용성 IV. 디자인패턴의유용성 가. 신규작업또는변화최소화 객체지향방법론의가장큰장점인재사용성과모듈성극대화 디자인뿐만아니라시스템구조재사용이용이해짐 개발에따른산출문서를보다향상 불명확한클래스기능, 객체간의부적절한연관관계등을제거해야하 작성자 : 이덕우페이지 4 / 11
`IV. 디자인패턴의 유용성 V. 추가참고자료 는시스템에대한유지보수성향상 나. 설계와코드품질의향상 정형화된틀을따름으로서오류와예외상황발생을최소화 일관된성능과균일한품질을유지하게함 공통된언어역할을함으로써중심점부여 업무영역이변경되어도프로그램의변경이비교적균일하게이루어져유지보수성향상 V. 추가참고자료 1. 생성패턴 : 객체생성할때사용되는여러가지방법들 (1) Factory Method : 추상클래스 A로부터상속받거나인터페이스 A를구현하는클래스들이있는경우팩토리클래스를이용해서원하는객체를생성한다. (2) Prototype : 객체를직접생성하지않고기존의객체를복사해서사용하는방법 (3) 싱글톤 : 클래스에오직하나의인스턴스만존재하여야하는경우클래스는직접적으로생성할수없도록생성자를 private로지정하고 static 메소드를통해오직하나의인스턴스를리턴하도로해야한다. 2. 구조패턴 : 클래스가다른클래스를통해구조적으로어떤연관관계를맺을수있는지보여준다. (1) 어댑터 : 기존에작성된클래스가있는새로필요한것은기존내용을이용하면서다른기능등혹은 API가필요한경우에사용 (ex : Circle, DrawableCircle Class) (2) 컴포지트 : 구조적정보중많은부분을재귀적인형태로표현할수있을때 Component로부터 leaf와 coposite는상속을받고, composite는 component를포함한다!! (Employee와 Manager의관계 ) (3) 데코레이터 : 기본적인기능이외에부가적인기능이필요할때부가기능이많고서로결합되어서사용될수있는경우데코레이터패턴사용 (4) Fecade 패턴 : 외부시스템과연결하는모든작업을한클래스에서맡아서하는방법을사용외부시스템의클래스들은내부구조와는무관하게데이터를처리할수있다. (5) 프록시 : 실질적인작업을수행하는 RealSubject 대신동일한 API를갖는 Proxy 클래스를이용해서클라이언트와메시지를주고받는방법 3. 행위패턴 : 여러개의클래스들이어떻게서로협력해서작업을수행하는지에대한내용 (1) Iterator : 클래스의내부에저장된데이터들이배열인지리스트인지모르도록하기위해사용되는패턴 (Collection관련클래스들 ) (2) 스테이트 : 객체는상태를가지면서각상태에따라다른행동을하게된다. (3) Starategy : 어떤작업을수행하는데어떤경우에는여러가지알고리즘이존재하고각알고리즘을구현해야할필요가있을때이용 (4) 템플릿 : 전체알고리즘이결정되었지만세부적인내용들이변경될수있는경우 작성자 : 이덕우페이지 5 / 11
VI. 패턴별설명 가. 스트래티지 (Strategy) 패턴 1) 스트래티지패턴 (Strategy Pattern) 정의 알고리즘군을정의하고각각을캡슐화하여교환해서사용할수있도록만듦 스트래티지를활용하면알고리즘을사용하는클라이언트와는독립적으로알고리즘을변경할수있음. 2) 스트래티지의필요성 알고리즘 ( 전략, 작전, 책략 ) 을교체해서동일한문제를다른방법으로해결하기위해실행중에교체하는것이가능하다. 여러알고리즘을미리만들어놓고필요할때마다원하는알고리즘을교체해서사용할경우에사용 3) 클래스를상속할경우의단점 서브클래스의코드중복 - 부모클래스에서메소드 fly() 를구현해놓았다면 (abstract 일때 ), 서브클래스에서는 fly() 를쓰지않아야할때매번안쓴다는코드를구현해놓아야함 - 불필요한행동들을그냥아무것도하지않는것으로오버라이드해야한다. - 만약규격이자주바뀌게되면매번프로그램에추가했던부모클래스를상속받은서브클래스의메소드를일일이살펴봐야한다. 실행시에특징을바꾸기힘들다 모든행동을알기힘들다. 코드를변경했을때다른클래스에원치않는영향을줄수있다. 4) 인터페이스를이용할경우의단점 자바인터페이스의경우를예를들면인터페이스에는구현된코드가전혀들어가지않기때문에코드재사용을할수없다. 즉한행동을바꿀때마다그행동이정의되어있는서로다른서브클래스들을전부찾아서일일이고쳐야하고, 그과정에서새로운버그가생길가능성이존재함 5) 인터페이스와추상 (Abstract) 클래스 Interface에는구현된메소드가없다. 모두선언만존재 Abstract Class는일부구현된메소드가있고추상메소드는하나이상있어야하고일반메소드도있을수있다. 6) 디자인패턴의포인트 소프트웨어를만들때, 나중에혹시고쳐야할때도기존코드에미치는영향은최소한으로줄이면서작업을할수있도록만들수있는방법이있다 7) 디자인원칙 애플리케이션에서달라지는부분을찾아내고, 달라지지않는부분으로부터분리시킨다. 달라지는부분을찾아서나머지코드에영향을주지않도록 캡슐화 한다. 그렇게하면나중에바뀌지않는부분에는영향을미치지않은채로그부분만고치거나 작성자 : 이덕우페이지 6 / 11
확장할수있다. 구현이아닌인터페이스에맞춰서프로그래밍한다. 상위 ( 추상 Class 나 interface) 형식에맞춰프로그래밍한다. 실제실행시에쓰는객체가코드에의해서고정되지않도록, 어떤상위형식 (supertype) 에맞춰서프로그래밍함으로써다형성을활용해야한다. Dog d = new Dog(); d.bark(); Animal animal = new Dog(); //Dog 을 Cat 으로바꿀수있다. 다형성이용 Animal.makeSound(); 더바람직한방법 // new Dog() 같은식으로직접코드를만드는대신구체적으로구현된 // 객체를실행시에대입하는것. A = getanimal(); a.makesound(); 상속보다는구성을활용한다. 구성 : A 는 B 이다 보다는 A 에는 B 가있다 가나을수있다. A 에는 B 가있다 관계에대해생각해보면각오리에는 FlyBehavior 와 QuackBehavior 가있으며, 각각행동과꽥꽥거리는행동을위임받는다두클래스를이런식으로합치는것을구성 (composition) 을이용하는것이라고부른다 8) 스트래티지패턴예 작성자 : 이덕우페이지 7 / 11
//StrategyExample test application class StrategyExample public static void main(string[] args) Context context; // Three contexts following different strategies context = new Context(new ConcreteStrategyAdd()); int resulta = context.executestrategy(3,4); context = new Context(new ConcreteStrategySubtract()); int resultb = context.executestrategy(3,4); context = new Context(new ConcreteStrategyMultiply()); int resultc = context.executestrategy(3,4); // The classes that implement a concrete strategy should implement this // The context class uses this to call the concrete strategy interface Strategy int execute(int a, int b); // Implements the algorithm using the strategy interface class ConcreteStrategyAdd implements Strategy public int execute(int a, int b) System.out.println("Called ConcreteStrategyA's execute()"); return a + b; // Do an addition with a and b class ConcreteStrategySubtract implements Strategy public int execute(int a, int b) System.out.println("Called ConcreteStrategyB's execute()"); return a - b; // Do a subtraction with a and b class ConcreteStrategyMultiply implements Strategy public int execute(int a, int b) System.out.println("Called ConcreteStrategyC's execute()"); return a * b; // Do a multiplication with a and b // Configured with a ConcreteStrategy object and maintains a reference to a Strategy object class Context private Strategy strategy; // Constructor public Context(Strategy strategy) 작성자 : 이덕우페이지 8 / 11
this.strategy = strategy; public int executestrategy(int a, int b) return strategy.execute(a, b); 나. 옵저버 (Observer) 패턴 1) 옵저버패턴의정의 한객체의상태가바뀌면그객체에의존하는다른객체들한테연락이가고자동으로내용이갱신되는방식으로일대다 (one-to-many) 의존성을정의. 2) 옵저버패턴의클래스정의예제 3) 옵저버패턴정리 옵저버패턴을이용하면주제객체에서데이터를보내거나 ( 푸시방식 ), 옵저버가데이터를 가져오는방식 ( 풀방식 ) 을쓸수있음 ( 풀방식이더옳은것으로간주되곤함 ). 4) 옵저버패턴샘플코드 /* 파일명 : EventSource.java */ package obs; import java.util.observable; 옵저버입니다. import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstreamreader; // 이부분이 작성자 : 이덕우페이지 9 / 11
public class EventSource extends Observable implements Runnable public void run() try final InputStreamReader isr = new InputStreamReader( System.in ); final BufferedReader br = new BufferedReader( isr ); while( true ) final String response = br.readline(); setchanged(); notifyobservers( response ); catch (IOException e) e.printstacktrace(); //----------------------------------------------------- /* 파일명 : ResponseHandler.java */ package obs; import java.util.observable; import java.util.observer; /* 여기가처리기 */ public class ResponseHandler implements Observer private String resp; public void update (Observable obj, Object arg) if (arg instanceof String) resp = (String) arg; System.out.println("\nReceived Response: "+ resp ); 작성자 : 이덕우페이지 10 / 11
//----------------------------------------------------- /* 파일명 : myapp.java */ /* 여기서부터가프로그램시작점 */ package obs; public class MyApp public static void main(string args[]) System.out.println("Enter Text >"); // create an event source - reads from stdin final EventSource evsrc = new EventSource(); // create an observer final ResponseHandler resphandler = new ResponseHandler(); // subscribe the observer to the event source evsrc.addobserver( resphandler ); // starts the event thread Thread thread = new Thread(evSrc); thread.start(); 작성자 : 이덕우페이지 11 / 11