행동패턴 편집하기
최신판 | 당신의 편집 | ||
1번째 줄: | 1번째 줄: | ||
− | ''' | + | '''행동 패턴'''(Behavioral patterns)은 오브젝트 사이의 상호작용과 오브젝트의 역할(책임)에 대한 것이다. 행위 패턴이라고도 한다.<ref name='be_main'>도킨샤, 〈[https://blog.naver.com/anciid/221763490051 Chapter 1.디자인 패턴 소개 ]〉, 2020-01-07</ref> |
− | |||
== 종류 == | == 종류 == | ||
− | === | + | === Chain of Responsibility 패턴 === |
− | + | 여러 개의 객체 중에서 어떤 것이 요구를 처리할 수 있는지를 사전에 알 수 없을 때 사용된다. 즉 요청 처리가 들어오게 되면 그것을 수신하는 객체가 자신이 처리 할 수 없는 경우에는 다음 객체에게 문제를 넘김으로써 최종적으로 요청을 처리 할 수 있는 객체의 의해 처리가 가능하도록 하는 패턴이다. | |
− | + | [[파일:Chain_of.jpg]]<br> | |
− | [[파일:Chain_of.jpg]] | ||
− | |||
위 그림을 보면 Sender 객체가 Handler 객체에 요청을 하며 그 요청이 수행되는 구조와 일련의 과정들이 나타나 있다.<br> | 위 그림을 보면 Sender 객체가 Handler 객체에 요청을 하며 그 요청이 수행되는 구조와 일련의 과정들이 나타나 있다.<br> | ||
왼쪽의 class diagram을 통해서 Handler 클래스를 상속하고 있는 다른 처리 클래스가 존재한다는 것을 알 수 있고, 오른쪽의 Sequence diagram을 통해서 그 과정이 Handler 클래스를 상속하고 있는 Receiver 1,2,3 클래스의 객체로 이루어진다는 것을 알 수 있다.<br><br> | 왼쪽의 class diagram을 통해서 Handler 클래스를 상속하고 있는 다른 처리 클래스가 존재한다는 것을 알 수 있고, 오른쪽의 Sequence diagram을 통해서 그 과정이 Handler 클래스를 상속하고 있는 Receiver 1,2,3 클래스의 객체로 이루어진다는 것을 알 수 있다.<br><br> | ||
이 패턴은 자바의 Exception Handling과 같은 원리인데 try문으로 코드를 실행시켜서 안되면 이어지는 catch문들이 그것을 처리하고 마지막에 finally가 처리한다는 면에서 비슷하다고 보는 것이다.<ref name='chain'>귤덕, 〈[https://sexycoder.tistory.com/105 Chain of Responsibility Pattern (책임 사슬 패턴) ]〉, 2018-03-02</ref> | 이 패턴은 자바의 Exception Handling과 같은 원리인데 try문으로 코드를 실행시켜서 안되면 이어지는 catch문들이 그것을 처리하고 마지막에 finally가 처리한다는 면에서 비슷하다고 보는 것이다.<ref name='chain'>귤덕, 〈[https://sexycoder.tistory.com/105 Chain of Responsibility Pattern (책임 사슬 패턴) ]〉, 2018-03-02</ref> | ||
− | + | === 커맨드(Command) 패턴=== | |
− | === | + | 커맨드 패턴은 사용자가 요구하는 명령어를 객체에 캡슐화(encapsulation)하여 저장한다. 각각의 명령어에 해당하는 객체는 그 명령어에 해당하는 기능을 실행하며, 필요에 따라 '명령 취소' 기능을 제공한다. 명령어와 관련된 사항이 객체에 캡슐화되어 있기 때문에, 사용자들은 단순히 그 명령어 객체를 생성해서 사용하기만 하면 된다. 또한, 이러한 명령어 객체들은 모두 공동의 상위 클래스를 갖고 있다. 이 상위 클래스는 각 명령어 객체의 클래스가 구현해야 할 메소드를 정의하고 있다. 예를 들어, 워드 프로세서에서 사용되는 '복사', '잘라내기', '붙여넣기'에 해당하는 명령어 클래스를 각각 CopyCommand, CutCommand, PasteCommand 라고 하고 이 세 클래스가 상속받는 추상 클래스를 AbstractCommand 라고 하면 전체적인 클래스 사이의 관계는 다음 그림과 같을 것이다.<ref name='command'>자바캔, 〈[https://javacan.tistory.com/entry/6 커맨드패턴과 그 구현 ]〉</ref><br> |
− | + | [[파일:command_pattern.gif]]<br> | |
− | |||
− | [[파일:command_pattern.gif]] | ||
− | |||
AbstractCommand 클래스는 모든 명령어 클래스가 상속받아야 할 클래스로서 추상 메소드인 execute()와 undo()를 선언하고 있다. 메소드의 이름에서 알 수 있듯이 execute() 메소드는 명령어에 해당하는 기능을 실행하기 위해 호출되는 메소드이며, 따라서 execute#40;) 메소드는 실제 기능을 구현하고 있다. 반면에 undo() 메소드는 '명령 취소'에 해당하는 기능을 제공한다. AbstractCommand 추상 클래스를 상속받는 클래스들은 그 클래스에 알맞도록 execute() 메소드와 undo() 메소드를 구현하면 된다. 예를 들어, CopyCommand 클래스의 execute() 메소드는 사용자가 설정한 블럭에 속한 글자들을 클립보드에 복사할 것이며, undo() 메소드는 클립보드에 저장되어 있는 글자들을 삭제할 것이다.<ref name='command'></ref> | AbstractCommand 클래스는 모든 명령어 클래스가 상속받아야 할 클래스로서 추상 메소드인 execute()와 undo()를 선언하고 있다. 메소드의 이름에서 알 수 있듯이 execute() 메소드는 명령어에 해당하는 기능을 실행하기 위해 호출되는 메소드이며, 따라서 execute#40;) 메소드는 실제 기능을 구현하고 있다. 반면에 undo() 메소드는 '명령 취소'에 해당하는 기능을 제공한다. AbstractCommand 추상 클래스를 상속받는 클래스들은 그 클래스에 알맞도록 execute() 메소드와 undo() 메소드를 구현하면 된다. 예를 들어, CopyCommand 클래스의 execute() 메소드는 사용자가 설정한 블럭에 속한 글자들을 클립보드에 복사할 것이며, undo() 메소드는 클립보드에 저장되어 있는 글자들을 삭제할 것이다.<ref name='command'></ref> | ||
− | 이제 남은 것은 각각의 명령어 객체를 저장하고 관리해주는 관리자 클래스인 CommandManager 클래스가 필요하다. 이 클래스는 실행되는 명령어를 차례대로 저장하고 있으며, 사용자가 '명령취소'를 요청할 경우 가장 최근에 저장된 명령어 객체의 undo() 메소드를 호출해주는 역할을 한다. 즉, 전체적인 클래스 사이의 관계는 다음과 같다. | + | 이제 남은 것은 각각의 명령어 객체를 저장하고 관리해주는 관리자 클래스인 CommandManager 클래스가 필요하다. 이 클래스는 실행되는 명령어를 차례대로 저장하고 있으며, 사용자가 '명령취소'를 요청할 경우 가장 최근에 저장된 명령어 객체의 undo() 메소드를 호출해주는 역할을 한다. 즉, 전체적인 클래스 사이의 관계는 다음과 같다.<br>[[파일:command_pattern2.gif]]<br> |
− | |||
− | [[파일:command_pattern2.gif]] | ||
− | |||
여기서 Invoker는 워드프로세서의 경우 사용자가 메뉴를 선택하거나 툴바를 클릭했을 때 발생하는 이벤트를 처리해주는 이벤트 리스너(예를 들어, ActionListener나 ItemListener 등)가 되며, ConcreteCommand 클래스는 CopyCommand와 CutCommand와 같이 실제 명령을 실행(구현)하는 명령어 객체를 나타낸다. CommandManager는 AbstractCommand를 관리하는 클래스이다.<ref name='command'></ref> | 여기서 Invoker는 워드프로세서의 경우 사용자가 메뉴를 선택하거나 툴바를 클릭했을 때 발생하는 이벤트를 처리해주는 이벤트 리스너(예를 들어, ActionListener나 ItemListener 등)가 되며, ConcreteCommand 클래스는 CopyCommand와 CutCommand와 같이 실제 명령을 실행(구현)하는 명령어 객체를 나타낸다. CommandManager는 AbstractCommand를 관리하는 클래스이다.<ref name='command'></ref> | ||
− | === | + | === 인터프리터(Interpreter) 패턴 === |
− | + | 문장을 해석할 때 사용하는 패턴이다. 간단한 셸 커맨드 처리, 통신 프로토콜 처리, 수식계산, 도메인 기반 언어(Domain Specific Language - SQL, XML, JSF등)의 해석에 주로 많이 쓰인다. 일반프로그래밍 언어처럼 문장구성이 복잡해지면 사용하지 않는 것이 낫다. | |
− | 중심이 되는 하나의 interprete 메소드에 많은 의무가 달려있기 때문에, 실제적으로 작성하는 코드에서 이 패턴을 사용해 코딩하는 일은 많지 않다. | + | 중심이 되는 하나의 interprete 메소드에 많은 의무가 달려있기 때문에, 실제적으로 작성하는 코드에서 이 패턴을 사용해 코딩하는 일은 많지 않다. <br> |
− | + | [[파일:interprete_pattern.png]]<br> | |
− | [[파일:interprete_pattern.png]] | + | Client는 문장해석의 주체이면서,인터프리터를 문장에 대해 적용한다. |
− | |||
− | |||
아래 다이어그램을 보면 TerminalExpression과 NonterminalExpression이 존재한다. 트리구조를 생각하면 편하다. 표현식안에 다른 표현식(자식 노드가 있는 경우)에는 다시 평가(Evaluation)을 수행해야 한다. Context는 interpreter(해석기)의 전역정보를 가지고 있다.<ref name='interpreter'>IDEO, 〈[https://m.blog.naver.com/PostView.nhn?blogId=2feelus&logNo=220664898533&proxyReferer=https:%2F%2Fwww.google.com%2F 인터프리터 패턴 - 자바 디자인 패턴과 JDK 예제 ]〉, 2016-03-25</ref> | 아래 다이어그램을 보면 TerminalExpression과 NonterminalExpression이 존재한다. 트리구조를 생각하면 편하다. 표현식안에 다른 표현식(자식 노드가 있는 경우)에는 다시 평가(Evaluation)을 수행해야 한다. Context는 interpreter(해석기)의 전역정보를 가지고 있다.<ref name='interpreter'>IDEO, 〈[https://m.blog.naver.com/PostView.nhn?blogId=2feelus&logNo=220664898533&proxyReferer=https:%2F%2Fwww.google.com%2F 인터프리터 패턴 - 자바 디자인 패턴과 JDK 예제 ]〉, 2016-03-25</ref> | ||
− | === | + | === 반복자(Iterator) 패턴 === |
− | + | 접근기능과 자료구조를 분리시켜서 객체화한다. 서로 다른 구조를 가지고 있는 저장 객체에 대해서 접근하기 위해서 interface를 통일시키고 싶을 때 사용하는 패턴이다.<br> | |
− | + | [[파일:iterator_pattern.png]]<br> | |
− | [[파일:iterator_pattern.png]] | ||
− | |||
* Iterator : 집합체의 요소들을 순서대로 검색하기 위한 인터페이스 정의 | * Iterator : 집합체의 요소들을 순서대로 검색하기 위한 인터페이스 정의 | ||
* ConcreateIterator : Iterator 인터페이스를 구현함 | * ConcreateIterator : Iterator 인터페이스를 구현함 | ||
− | * Aggregate : 여러 요소들로 이루어져 있는 집합체<ref name='iterator'>Lkt_Programmer, 〈[https://lktprogrammer.tistory.com/40 08 반복자 패턴(Iterator Pattern) ]〉, 2017-09-24</ref> | + | * Aggregate : 여러 요소들로 이루어져 있는 집합체 |
+ | <ref name='iterator'>Lkt_Programmer, 〈[https://lktprogrammer.tistory.com/40 08 반복자 패턴(Iterator Pattern) ]〉, 2017-09-24</ref> | ||
− | === | + | === 미디에이터(Mediator) 패턴 === |
− | + | 한 집합에 속해있는 객체들의 상호 작용을 캡슐화하는 객체를 정의하는 패턴이다. 중재자는 객체들이 직접 서로 참조하지 않도록 함으로써 객체들 간의 느슨한 연결을 촉진시키며 객체들의 상호작용을 독립적으로 다양화시킬 수 있도록 해준다. | |
− | + | === 옵저버(Observer) 패턴 === | |
+ | 객체들 사이에 1 : N 의 의존관계를 정의하여 어떤 객체의 상태가 변할 때, 의존관계에 있는 모든 객체들이 통지받고 자동으로 갱신될 수 있게 만드는 패턴이다. | ||
− | + | === 상태(State) 패턴 === | |
+ | 객체의 내부 상태가 변경될 때 행동을 변경하도록 허락한다. 객체는 자신의 클래스가 변경되는 것처럼 보이게 된다. | ||
− | === | + | === 스트레이트지(Strategy) 패턴 === |
− | + | 동일 계열의 알고리즘들을 정의하고 각각 캡슐화하며 이들을 상호교환 가능하도록 만드는 것이다. 알고리즘을 사용하는 사용자로부터 독립적으로 알고리즘이 변경될 수 있도록 하는 패턴이다. | |
− | + | === 템플릿(Template) 패턴 === | |
+ | 객체의 연산에서 알고리즘의 뼈대만 정의하고, 나머지는 서브클래스에서 이루어지게 하는 패턴이다. 템플릿 패턴은 알고리즘의 구조는 변경하지 않고 알고리즘의 각 단계를 서브클래스에서 재정의하게 된다. | ||
− | + | === 비지터(Visitor) 패턴 === | |
+ | 객체구조를 이루는 원소에 대해 수행할 연산을 표현한다. 방문자는 연산에 적용할 원소의 클래스를 변경하지 않고 새로운 연산을 재정의 할 수 있다. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{{각주}} | {{각주}} | ||
== 참고자료 == | == 참고자료 == | ||
− | * | + | * |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== 같이 보기 == | == 같이 보기 == | ||
− | * | + | * |
− | |||
{{프로그래밍|검토 필요}} | {{프로그래밍|검토 필요}} |