본문 바로가기

PROGRAMMING

[GoF] 명령 (Command) 패턴 명령 (Command) 패턴 행동 패턴명령을 객체의 형태로 캡슐화하여 동적으로 명령을 수행할 수 있고, 명령을 저장함으로써 명령을 지연시키거나 되돌릴 수 있게 합니다. 게임 속 플레이어를 키보드나 조이스틱을 통해 조종해 본 경험이 있을 것이다. 유저가 WASD 키를 누르거나 조이스틱을 어느 방향으로 당긴다면, 게임 속 지정된 규칙에 따라 플레이어는 움직이게 된다. 게임을 프로그래밍적인 관점으로 본다면, 외부 입력을 제어하는 부분과 플레이어를 조종하는 부분은 분명히 따로 분리되어 있을 것이다.하지만 단순히 외부 입력에서 함수를 호출함으로써 플레이어를 조종하게 하려면, 외부 입력을 제어하는 부분에선 게임 속의 특정한 플레이어(대상)를 알아야만 할 것이다. 서로 둘은 연관이 거의 없는데도 강하게 결합되어 있는..
[GoF] 관찰자 (Observer) 패턴 [GoF] 관찰자 (Observer) 패턴 행동 패턴객체가 다른 객체의 상태 변화를 구독할 수 있게 하며, 구독한 객체의 상태가 갱신될 경우 객체에게 통지하여 갱신된 상태를 활용할 수 있도록 합니다. 요즈음 다양한 게임의 유저 인터페이스(UI)를 들여다보면, 게임 내부의 상태가 변함에 따라 유저 인터페이스도 자동으로 변하는 모습을 볼 수 있다. 예를 들어, 게임이 시작된다면 게임 진행을 위한 메뉴가 보여진다던가, 플레이어의 체력이 감소하면 HP 바가 덩달아 줄어드는 등. 이 두 개념은 서로 거리가 멀어 보이는데, 유저 인터페이스는 어떻게 상태 변화를 감지하고 대응하는것인가? 대부분의 경우 관찰자 패턴을 사용하여 구현할 수 있다.관찰자 (Observer) 패턴은 관찰하고자 하는 객체에 상태가 변경 될 경우..
[GoF] 책임 연쇄 (Chain of Responsibility) 패턴 책임 연쇄 (Chain of Responsibility) 패턴 행동 패턴요청에 대한 처리를 여러 객체를 통해 연쇄적으로 수행합니다. 처리를 요청으로부터 분리하기 위하여 클라이언트는 요청에 대해 처리할 수 있는 객체를 정의할 수 있다. 그런데, 요청에 대한 처리가 확장되기를 요구할 경우 이에 대한 구현도 추가될 수 밖에 없는데, if . . . else if . . . else 문을 통해 한 객체 안에 모든 처리를 우겨넣기엔 객체 지향 프로그래밍의 단일 책임 원칙을 위배한다.그래서 책임 연쇄 (Chain of Responsibility) 패턴은 요청을 처리하는 객체를 책임에 따라 여러개로 나누고, 이들을 서로 연결하여 처리를 동적으로 수행한다. 객체가 요청을 받으면, 객체가 책임하는 처리를 수행한 다음에 ..
[GoF] 메멘토 (Memento) 패턴 메멘토 (Memento) 패턴 행동 패턴객체의 상태를 저장할 수 있는 객체를 통해 객체의 상태를 되돌릴 수 있게 합니다. 컴퓨터 소프트웨어의 대부분은 사용자의 기호에 알맞게 소프트웨어를 사용할 수 있도록 환경 설정이라는 기능을 지원한다. 사용자는 환경 설정이 제공하는 인터페이스를 통해 소프트웨어의 환경을 설정하고 이를 소프트웨어에 적용할 수 있다. 이 때, 사용자가 설정한 환경이 마음에 들지 않을 경우, 취소를 통해 환경을 설정 이전으로 되돌릴 수가 있다. 환경 설정은 설정하기 이전의 환경을 어떻게 되돌릴 수 있었을까?메멘토 패턴은 객체의 상태를 저장할 수 있는 메멘토 객체를 정의하여, 객체의 상태를 메멘토 객체에 저장한 후 클라이언트의 요구에 따라 메멘토 객체를 통해 객체의 상태를 복원할 수 있다.메멘..
[GoF] 싱글턴 (Singleton) 패턴 싱글턴 (Singleton) 패턴 생성 패턴클래스에 대응하는 단일의 객체에 대한 전역적인 접근을 허용합니다. 어떤 객체는 어떤 코드 영역에서든지 접근할 수 있어야 할 경우가 있다. 환경 설정을 불러오거나, 진행중인 게임의 상태를 가져오거나, 쓰레드 풀을 사용할 경우에 관련 객체에 접근해야 할 것이다. 그럴 때마다 객체를 가져오기엔 실제로 객체가 있는 구조와는 거리가 멀 수도 있고, 객체를 일시적으로 사용하기 위해 생성자 등을 통해 객체를 가져와야 하는 것도 번거로울 것이다. 싱글턴 패턴은 객체가 곧 클래스(객체를 하나만 생성할 수 있음)인 경우에 한해 객체에 대한 전역적인 접근을 허용할 수 있게 한다.전역 멤버 변수는 클래스 네임스페이스를 통해 프로그램 내 어디에서든지 접근 가능하다는 특징이 있다. 그래..
[GoF] 프로토타입 (Prototype) 패턴 프로토타입 (Prototype) 패턴 생성 패턴원형이 되는 객체를 사용하여 생성할 객체의 종류를 정의하고, 이를 복제하여 새로운 객체를 생성합니다. 클라이언트는 간혹 객체를 독립적으로 복제해서 사용하고자 할 때가 있다. 이럴 경우, 단순히 객체를 새로 생성해야 할 뿐만 아니라, 객체 내부의 값을 모두 복사해야 할 것이다. 클라이언트가 직접 객체의 내부 값을 모조리 가져와서 새로 생성된 객체에 다시 넣어준다면 복제가 되었다고 할 수 있겠지만, 그것은 객체와의 의존이 생긴다는 의미를 가지기도 하고 객체가 복잡해진다면 감당하기 어려워질 수 있다.그래서 원형 (Prototype) 이란 뜻을 가진 프로토타입 패턴은 객체를 복제할 수 있도록 해당 클래스 내에 복제에 대한 내용을 구현하여, 객체를 통해 복제된 객체를..
[GoF] 팩토리 메서드 (Factory Method) 패턴 팩토리 메서드 (Factory Method) 패턴 생성 패턴클래스의 상속을 통해 하위 객체의 생성을 정의합니다. 객체는 단일의 책임을 부과하기 위해 생성될 때나 사용 중일 때 필요에 따라 하위 객체를 추가적으로 생성하고 할당하여 객체의 기능을 확장할 수도 있다. 하지만, 클래스의 상속을 거친 하위 클래스는 속성이 다른 객체를 요구할 수도 있는데, 이 기능을 하나의 상위 클래스 내에서 정의하려면 switch-case 문과 같은 조건문을 통해 생성해야 할 객체의 속성을 정의해야 한다. 그러나, 이것은 끊임없이 확장하는 클래스 상속 구조에선 적절하지 않다. 하위 클래스의 속성을 확장해야 할 경우 생성을 구현하는 조건문을 직접 수정해야 하기 때문이다.그래서 팩토리 메서드 패턴은, 상위 클래스에서 생성해야 할 객..
[GoF] 빌더 (Builder) 패턴 빌더 (Builder) 패턴 생성 패턴많은 매개변수를 필요로 하는 객체의 생성을 단계적으로 진행합니다. 보통 객체를 생성할 때에는, 생성자를 통해 매개 변수를 객체에게 넘겨 초기 설정을 하도록 지시를 한다. 이것은 확실한 객체의 초기 설정을 보장한다. 그러나, 생성자를 통해 전달해야 할 매개 변수가 다양할 경우에는 클라이언트가 생성자에게 전달해야 할 매개 변수의 의도를 파악하기 어려워지고, 전달하고 싶지 않은 매개 변수조차 모두 전달해야 하는 상황이 발생한다. (이에 대한 해결책으로 다양한 언어에서는 디폴트 매개 변수를 지원하지만, 이마저도 한계가 있다.)그래서 빌더 패턴은 생성자를 통해 객체를 직접 생성하는 대신에, 빌더 객체가 객체의 생성을 대신 수행하게 된다. 그리고, 클라이언트가 빌더 객체의 인터..
[GoF] 추상 팩토리 (Abstract Factory) 패턴 추상 팩토리 (Abstract Factory) 패턴 생성 패턴관련성이 있는 여러 객체로 이루어진 구조의 생성을 정의합니다. 클라이언트는 상황에 따라 다른 구조를 생성해야 할 때가 있다. 그렇다면, enumeration이나 string을 인자로 받아 switch-case 문으로 하여금 생성할 구조의 속성을 지정할 수 있으나, 생성해야 할 구조의 가짓수가 많아질수록 생성에 대한 부가적인 기능을 추가하기 위해 함수를 수정해야 함으로 유연성이 떨어질 수 있다.그래서 추상 팩토리 패턴은 구조의 생성을 수행하는 팩토리 클래스를 정의하여 클라이언트가 팩토리 클래스의 인터페이스를 통해 구조를 생성할 수 있게 한다. 추상 팩토리 구조의 생성에 관한 구체적인 내용이 팩토리 클래스에서 구현되기에 구조의 생성에 대한 유연한 ..