State Pattern

스테이트 패턴을 정리한다.

FSM (Finite State Machine)

지하철 개찰구가 동작하는 방식에서 간단한 유한 상태 기계 (FSM: Finite State Machine) 의 예를 보자.
아래 다이어그램을 STD (State Transition Diagram) 이라고 한다.

  • 기계가 Locked 상태에서 coin 이벤트를 받으면, Unlocked 상태로 전이가 되고 unlock 행동을 호출
  • 기계가 Unlocked 상태에서 pass 이벤트를 받으면, Locked 상태로 전이가 되고 lock 행동을 호출

같은 의미로 STT (State Transition Table) 로도 표현할 수 있다.

1
2
Locked      coin    Unlocked    unlock
Unlocked pass Lokced lock

이 도구의 장점은, 설계자가 이상한 조건 또는 그 조건을 다룰 행위의 정의되지 않은 조건을 찾기 쉽다.
에를 들어,

  • Unlocked 상태에서 coin 이벤트를 다루는 전이가 없고,
  • Locked 상태에서 pass 이벤트를 다루는 전이도 없다.

추가해보자.

Read more

Abstract Server, Adapter Pattern

추상 서버 패턴과 어뎁터 패턴을 정리한다.

탁상 스탠드 설계

탁상 스탠드 내부의 소프트웨어를 설계해보자.
단순하게 다음과 같이 설계할 수 있다.

이 설계의 문제는,

  1. DIP 위반: Light 로 향하는 의존 관계가 구체 클래스에 대한 의존 관계이다.
  2. Switch 는 Light 이외의 객체를 제어할 수 있도록 확장이 힘들다.

추상 서버 패턴

Switch 와 Light 사이에 인터페이스를 도입해서, Switch 가 무엇이든 제어할 수 있게 만들 수 있다.

여기서 주목할 것은, 인터페이스의 이름이 ILight 가 아니라 Switchable 이다.
즉, 인터페이스의 클라이언트인 Switch 를 위한 쪽으로 인터페이스 이름을 지었다.
인터페이스는 파생 클래스나 파생 인터페이스에 속하는 것이 아니라, 클라이언트에 속하기 때문이다.

Read more

Composite Pattern

Composite Pattern 을 정리한다.

Sensor-Command 예제

Sensor 는 무엇을 감지하면 Command 의 do() 를 호출한다.
Command 를 하나 이상 실행해야하는 경우도 있다.
하나 이상 실행해야할 때는, Sensor 가 목록을 순회하면서 각 Command 의 do() 를 호출한다.

Composite Pattern 적용

Command 에 복수성 개념을 추가해서 다음과 같이 Composite 패턴을 사용할 수 있다.

다수성

composite 패턴을 사용하면 일대다 관계 없이도 일대다의 행위를 할 수 있다.
클래스의 클라이언트마다 목록 관리와 순환 코드를 중복해서 사용하는 대신, 그 코드가 컴포지트 클래스에서만 사용하게 된다.


Read more

Factory Pattern

Factory Pattern 을 정리한다.

new Circle 예시

DIP 에 따르면, 구체 클래스에 의존하지 말고 추상 클래스에 의존해야한다.
다음 코드는 DIP 를 위반한다.

1
Circle c = new Circle(origin, 1)

Circle 은 구체 클래스이기 때문에, Circle 인스턴스를 생성하는 모듈은 DIP 를 어긴다.

다만, DIP 위반이 해롭지 않은 경우가 있다.
구체 클래스가 쉽게 변경되는 종류의 클래스가 아닌 경우이다. ex) String

팩토리 패턴 적용

팩토리 패턴을 사용하면 추상 인터페이스에만 의존하면서 구체적인 인스턴스를 만들 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface Shape

public interface ShapeFactory {
public Shape makeCircle();

public Shape makeSquare();
}

public class ShapeFactoryImplementation implements ShapeFactory {

public Shape makeCircle() {
return new Circle();
}

public Shape makeSquare() {
return new Square();
}
}

trade-off

Read more

Principles of Package Design

큰 애플리케이션을 조직화하기 위해서는, 클래스보다 더 큰 package 가 필요하다.
패키지의 응딥도에 대한 원칙과 결합도에 대한 원칙을 정리한다.

  1. 패키지 응집도에 대한 원칙: 클래스를 패키지에 할당하는 것을 도와준다.
  2. 패키지 결합도에 대한 원칙: 패키지 간 관계를 결정하는 것을 도와준다.

패키지 응집도에 대한 원칙

패키지 응집도에 대한 원칙은 아래 세 가지가 있다.

  1. 재사용 릴리즈 등가 원칙 (REP: Reuse-Release Equivalent Principle)
  2. 공통 재사용 원칙 (CRP: Common-Reuse Principle)
  3. 공통 폐쇄 원칙 (CCP: Common-Closure Principle)

재사용 릴리즈 등가 원칙

재사용의 단위는 릴리즈 단위다.

재사용하는 모든 것은 반드시 릴리즈 된 다음에 추적 가능해야한다.
사용자들에게 필요한 통보, 안정성, 지원에 대한 보장을 제공하는 추적 시스템이 먼저 있어야 재사용성이라는 말을 할 수 있다.
재사용성은 패키지에 기반을 두어야하기 때문에, 재사용 가능한 패키지는 재사용 가능한 클래스를 포함해야한다.

또한, 재사용성 뿐만 아니라 재사용자가 누구인지도 고려해야한다.
컨테이너 클래스 라이브러리는 사용하고 싶지만, 금융 관련 프레임워크에는 관심 없는 사람이 있을 수 있다.
패지지 안의 모든 클래스는 동일한 재사용자를 대상으로 해야한다.

공통 재사용 원칙

Read more