분류 전체보기 42

[Design Patterns] Visitor

목차개요내용요약객체들에 적용되어야 할 연산을 정의한 후, 기존 클래스의 변경없이 새로운 연산을 할 수 있도록 하자.예시AST(abstract syntax tree)을 생성하는 컴파일러를 생각해봅시다. 이 컴파일러는 생성된 AST에 의미 분석을 해야합니다. 이를 위해 컴파일러는 타입 체크, 코드 최적화 등을 해야 합니다. 이를 위해 아래와 같은 클래스 구조를 생각해볼 수 있습니다.하지만 이런 방식을 채택하면 모든 연산들이 다양한 노드 클래스에 분산되어있어 시스템을 유지보수하고 변경하기 어려워집니다. 새로운 연산이 독립적인 클래스에 정의되고, 노드 클래스와 상관없이 된다면 유지보수하기 더 나을겁니다.  그렇게 하기 위해서 연관된 연산을 별도의 객체인 비지터로 빼내고 이를 노드에 넘겨주는 방식을 사용할 수 있..

Design Patterns 2024.06.17

[Design Patterns] Template Method

void openDocument(name) { if (!canOpenDocument(name)) { return; } Document doc = createDocument(name); if (doc) { addDocuments(doc); doc.read(); }}​  목차개요내용요약알고리즘의 기본 뼈대를 정의하고 각 스텝을 하위 클래스가 작성하도록 하자. 예시문서를 읽는 애플리케이션을 생각해봅시다. 여기서 문서는 로컬에서 가져오는 PDF, spreadsheet 혹은 REST API로 받아오는 JSON 등 여러가지가 될 수 있습니다. 이러한 문서를 열어서 일관된 포맷으로 파싱해주는 알고리즘을 어떻게 만들어야 할까요? 이와 관련된 알고리즘에 대해 아래와..

Design Patterns 2024.06.16

[Design Patterns] Strategy

목차개요내용요약알고리즘 집합을 정의하고 각각을 하나의 클래스로 캡슐화해서 골라서 사용할 수 있게 하자.예시출처 - https://stackoverflow.com/questions/370258/real-world-example-of-the-strategy-pattern 파일 하나를 암호화해야 한다고 생각해봅시다. 크기가 작은 파일이라면, 메모리 안에서 모든걸 해결하는 알고리즘을 쓰고 싶을 겁니다. 반면에 크기가 큰 파일이라면, 부분적으로 디스크에 저장하는 알고리즘을 써야할 수 있습니다. 이럴 때 전략 패턴을 사용할 수 있습니다.File file = getFile();CipherContext context = new CipherContext();Cipher c = context.getCipher(file.g..

Design Patterns 2024.06.16

[Design Patterns] State

목차개요내용요약내부 상태가 변경되면 행동도 바꾸자. 예시TCP 연결을 하는 TCPConnection 클래스가 있다고 생각해봅시다. 이 클래스의 객체는 여러 상태를 가질 수 있습니다: Eastablished, Listening, Closed. 다른 객체로부터 요청을 받았을 때, TCPConnection 객체는 상태에 따라 다르게 으답해야 합니다. 이 문제를 해결하기 위해선 TCPState라는 추상 클래스를 두는 겁니다.  TCPConnection 객체는 상태 객체를 가집니다. 이 클래스는 상태와 관련된 연산을 모두 상태 객체에게 위임합니다. 이를 상태 패턴이라고 합니다.이야깃거리언제 써야 할까?객체의 행동이 상태에 달려있고 행동을 런타임에 바꿔야 할 때장단점(Pros) 상태 변화를 명시적으로 만듭니다.(C..

Design Patterns 2024.06.09

[Design Patterns] Observer

목차개요내용요약객체간에 1 : N 연관관계를 설정해서 한 객체가 상태를 바꿀 때, 연관된 모든 객체들에게 알리자동기클래스를 나누다보면 연관된 객체들간에 일관성을 지키기가 힘들어진다. 그렇다고 객체를 강하게 결합시키자니 재사용성이 떨어진다.. 이럴 때 옵저버 패턴을 사용할 수 있다.이 패턴의 핵심 객체는 옵저버와 관찰 대상(subject) 객체이다. 관찰 대상 객체에서 상태 변화가 나타나면 옵저버 객체들의 메소드를 호출한다. 이러한 상호작용은 publish-subscribe로도 알려져있다.구조이야깃거리언제 써야 할까?자신의 상태가 변화했을 때 대상 객체가 누구냐와 관계없이 이를 알려줘야하는 객체가 있을 때한 객체의 상태 변화가 다른 객체의 상태 변화로 이어져야하고 얼마나 많은 다른 객체가 있을지 알 수 없..

Design Patterns 2024.06.09

[Design Patterns] Memento

목차개요내용요약캡슐화를 위반하지 않고, 나중에 상태를 복구하기 위해 객체의 내부 상태를 밖으로 노출시키자예시객체의 내부 상태를 기록해두는건 중요할 때가 있습니다. 체크포인트를 구현하거나 undo를 해야할 때 특히 필요한데요. 하지만 객체들은 일반적으로 자신들의 상태를 캡슐화해서 외부로 노출시키지 않습니다. 이럴 때 메멘토 패턴을 쓸 수 있습니다. 메멘토는 다른 객체의 내부 상태 스냅샷을 저장하는 객체입니다. 이 때, 내부 상태가 저장되는 다른 객체를 메멘토의 창시자라고 합니다.메멘토에서 상태를 가져오는 것은 오직 창시자만 가능합니다. 구조이야깃거리언제 써야 할까?나중에 복구하기 위해 객체의 상태를 저장해야만 할 때객체의 상태를 직접적으로 얻는 것이 세부 구현을 노출하고 캡슐화를 깰 때장단점(Pros) 캡..

Design Patterns 2024.06.06

[Design Patterns] Mediator

목차개요내용요약객체 집합이 소통하는 방식을 캡슐화하는 객체를 정의하자.예시 객체 지향에서는 코드를 나눠 한가지 일을 하는 코드 묶음으로 클래스를 구성하도록 합니다. 때로는 이런 방식이 객체들 사이에 많은 연결이 있는 구조를 만들기도 합니다. 최악의 상황으로, 모든 객체들이 거의 모든 다른 객체들을 알게끔 할 수 있습니다. 비록 시스템을 많은 클래스로 나누는 것은 재사용성을 증가시키지만, 객체간에 연결이 너무 많아지면 오히려 다시 재사용성을 떨어뜨립니다. 다음 예제를 생각해봅시다. 우리는 GUI 프레임워크를 만드는 중에 다이럴로그를 구현해야 합니다. 다이럴로그 박스는 버튼, 메뉴, 인풋 등의 컴포넌트들을 보여주기 위해 하나의 창을 사용합니다. 보통 이럴 때 다이얼로그 안에 있는 컴포넌트들은 서로 상호작용을..

Design Patterns 2024.05.13

[Design Patterns] Iterator

목차 개요 내용 요약 다른 객체들을 가지고 있는 객체(aggregate object)에서 내부 구현을 몰라도 그 안에 있는 객체를 순서대로 접근할 수 있게 해주자 예시 리스트와 같은 자료구조들은 그 안에 있는 요소들을 순회할 수 있는 방법을 제공해줘야 합니다. 또한 요구에 따라 다양한 방식으로 순회할 수 있는 방법을 제공해줄 수도 있어야 합니다. 그렇다면 수많은 요구를 가정하고 이 모든 케이스에 대한 메소드를 리스트 인터페이스에서 제공해줘야 할까요? 이렇게 함으로써 리스트 인터페이스가 비대해지면 사용하기 까다로워질 것입니다. 이럴 때 이터레이터 패턴을 사용할 수 있습니다. 리스트 이터레이터 클래스를 객체화하려면 순회 대상이 되는 리스트 클래스를 줘야하는데요. 이렇게 순회 방법을 리스트 인터페이스와 분리함..

Design Patterns 2024.04.21

[Design Patterns] Interpreter

목차 개요 내용 요약 언어가 주어지면 그 언어의 문법에 대한 표현법을 정하고 인터프리터를 사용해 문장을 해석하자. 예시 문자열에서 특정한 패턴을 찾을 땐 어떻게 해야 할까요? 예를 들어, 해당 문자열이 전화번호라는 것을 어떻게 검증할 수 있을까요? 기초적으로 생각해보면 아래처럼 구현할 수 있을 것입니다. str.isDecimal(0, 2) && str.charAt(3).equals("-") . . . 하지만 어떤 패턴을 찾을 때마다 위처럼 일일히 구현해주면 상당히 귀찮겠죠? 이때문에 등장한 것이 Regulater Expression, 줄여서 regex입니다. Regex는 문자열에서 특정한 패턴을 찾을 때 도움을 주는 DSL입니다. 이처럼 특정한 목적을 위해 언어를 정의하고 해석하는 패턴을 인터프리터 패턴..

Design Patterns 2024.04.21

[Design Patterns] Command

목차 개요 내용 요약 사용자가 다양한 요청을 할 수 있고 로깅을 하는 등의 추가 작업을 하기 위해서 커맨드를 객체로 감싸자 예시 GUI 프레임워크를 만든다고 생각해봅시다. 버튼 컴포넌트를 만들었을 때 사용자가 클릭했을 때 어떤 액션을 취해야할까요? 정답은 이 프레임워크를 이용해 애플리케이션을 만드는 사용자 마음이겠죠. 즉, 프레임워크 개발자는 버튼 컴포넌트를 만들 때 버튼을 클릭했을 시 어떤 액션을 취해야하는지 모릅니다. 이 때 사용할 수 있는 방법이 커맨드 패턴입니다. 커맨드 패턴에선 커맨드라는 인터페이스를 가집니다. 이 인터페이스는 인자를 받지 않는 execute() 라는 메소드 하나를 가집니다. 위의 예제에선 버튼 객체가 이 커맨드 인터페이스를 구현한 concrete class를 멤버로 가집니다. ..

Design Patterns 2024.03.31