레이블이 디자인 패턴인 게시물을 표시합니다. 모든 게시물 표시
레이블이 디자인 패턴인 게시물을 표시합니다. 모든 게시물 표시

2013년 1월 31일 목요일

커맨드 패턴(Command Pattern)

출처: Head First Design Patterns : 스토리가 있는 패턴 학습법

커맨드 패턴(Command Pattern)
커맨드 패턴을 이용하면 요구 사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러 가지 다른 요구 사항을 집어 넣을 수도 있다. 또한 요청 내역을 큐에 저장하거나 로그로 기록 할 수 있으며, 작업 취소 기능도 가능 하다.


이건 알게 모르게 자주 사용하고 있는 패턴이다. 특히 요즘 언어들은 자체적으로 커맨드 패턴 방식으로 코딩 할 수 있게 function 을 제공해 주므로, 그것을 이용하면 자동적으로 커맨드 패턴 형식으로 결과물이 나온다.

2013년 1월 29일 화요일

싱글턴 패턴(Singleton Pattern)

출처: Head First Design Patterns : 스토리가 있는 패턴 학습법

싱글턴 패턴(Singleton Pattern)
싱글턴 패턴은 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴이다.

디자인 패턴을 모르더라도 대부분 알고 있고 유용하게  사용하고 있는 패턴이다. 책에서는 보통 사용하고 있는 싱글턴 패턴 코드에 대해서 고전적인 싱글턴 패턴이라고 말을 하면서, 멀티쓰레드에서는 제대로 작동하지 않는다고 하는데... 멀티쓰레드 되면 프로그램 구조에 대해서 다시 생각해 봐야 하므로 당연한 말이 아닌지....

아무튼 이건 Class Diagram 보다는 코드를 보는게 더 이해가 빠르다.(Class Diagram 에 박스 하나 밖에 없으므로....)

[Java]
1. Thread-unsafe
public class Singleton {
    private static Singleton uniqueInstance;

    private Singleton() {}

    public static Singleton getInstance() {
        if(uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

2. Thread-safe
public class Singleton {
    private volatile static Singleton uniqueInstance;
    
    private Singleton() {}

    public static Singletone getInstance() {
        if(uniqueInstance == null) {
            synchronized(Singleton.class) {
                if(uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
    }
}


[Objective C]
1. Thread-safe
@impelement Singoleton
static Singleton* sharedInstance = nil;
+ (id)sharedInstance {
    if(sharedInstance != nil) return sharedInstance;
    
    static dispatch_once_t pred;
    dispatch_once(&pred, ^{
        sharedInstance = [[self alloc] init];
    });
    
    return sharedInstance;
}
@end

멀티쓰레드가 된다면 만들어 놓고 디버깅 하려면 무지 힘드니, Singleton 을 사용한다면 프로그램 구조 설계 할때 잘 생각해서 구현 하도록 하자. 생성 외에 내부 메소드들도 멀티쓰레드 동작이 반영 되어야 할 것이다.

추상 팩토리 패턴(Abstract Factory Pattern)

출처: Head First Design Patterns : 스토리가 있는 패턴 학습법

추상 팩토리 패턴(Abstract Factory Pattern)
추상 팩토리 패턴에서는 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상 클래스를 지정하지 않고도 생성 할수 있다.

흠...이건 좀 괜찮다.

Factory method pattern 과 엮여 있는 패턴이다. Abstract factory pattern 은 내부에서 Factory method pattern 으로 구현 되어 진다.

그런데, Factory method pattern 은 상속을 통해 factory 가 구현되는 것이고, Abstract factory pattern 은 객체 중심으로 factory 가 구현되는 중요한 차이점이 있다.

factory pattern 은 상황에 맞게 factory method 를 사용할 것인지, abstract factory 를 사용할 것인지 판단 하면 되겠다.

대부분의 경우 factory method 만으로 충분 할 듯....

팩토리 메소드 패턴(Factory Method Pattern)

출처: Head First Design Patterns : 스토리가 있는 패턴 학습법

팩토리 메소드 패턴(Factory Method Pattern)
팩토리 메소드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만듭니다. 팩토리 메소드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡긴다.

이건 좀 실망한 디자인 패턴이다. 팩토리 형식(디자인 패턴이 아니라고 하나 뭐라나...)으로 코딩을 하는 것과 팩토리 메소드 형식으로 코딩을 하는 것을 나누어 두었는데, 실제 코딩을 하다보면 아무 생각 없이 팩토리 형식으로 만들다 보면 결국에는 팩토리 메소드 패턴이 나올수 밖에 없다.

2013년 1월 7일 월요일

데코레이터 패턴(Decorator Pattern)

출처: Head First Design Patterns : 스토리가 있는 패턴 학습법

데코레이터 패턴(Decorator Pattern)
객체에 추가적인 요건을 동적으로 첨가한다. 데코레이터는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.

데코레이터 라니 정말 잘 지은 이름이 아닌가, 솔직히 데코레이터 패턴은 내용 보다는 이름에 감탄을 한 디자인 패턴이다.

Head First Design Patterns 의 예제가 정말 상황에 맞게 잘되어 있어서 Class Diagram 을 몇 부분 수정하여 사용하고 있다. 데코레이터 패턴과 별다방 커피 종류라니 정말 딱 맞는 예시 이다.

데코레이턴 패턴은 실제로 java.io 에서 처음 접해 본 것인데, 진짜 처음 보면 클래스 갯수에서 막막함을 느끼기도 할만한 패턴 일듯도 하다.

2013년 1월 6일 일요일

옵저버 패턴(Observer Pattern)

출처: Head First Design Patterns : 스토리가 있는 패턴 학습법

옵저버 패턴(Observer Pattern)
한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의 한다.

subject 가 observer 에서 push 로 정보를 내리는 것과 observer 가 subject 에서 정보를 pool 할 수 있도록 하였다. pool 이 있으면 기능적으로 좋을듯 한데, 이렇게 되니 뭔가 꼬이는 느낌이 든다.

스타크래프트 observer 때문에, subject 와 observer 의 역할을 반대로 생각하는 함정이 있을수도 있을듯 하다.

참고로 패키지로 묶은 것은 ArgoUML 을 제대로 사용하지 못하여 Class Diagram 그룹핑을 어떻게 시킬줄 몰라서 묶은거라는....ㅜㅜ

2013년 1월 4일 금요일

스트래티지 패턴(strategy pattern)

출처: Head First Design Patterns : 스토리가 있는 패턴 학습법

스트래티지 패턴(Strategy Pattern)
알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 스트래티지 패턴을 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경 할 수 있다.


클래스 다이어그램에서 보듯이 MallardDuck, RedheadDuck, RubberDuck, DecoyDuck 에 대해서 fly, quack 하는 행동이 다르다.

때문에 공통 부분은 Duck 에서 구현을 하고, 다른 부분은 interface-class 로 그룹화 시킨 또 다른 알고리즘 군에서 구현하고 있다.

개발자가 사용하는 MallardDuck, ..., DecoyDuck 에서는 각각에 따른 display 를 override 시키고, setFlyBehavior, setQuackBehavior 를 통해서 부모 클래스(Duck)의 flyBehavior, quackBehavior 를 설정 한다.

결국 어느 Duck 에서 fly, quack 을 하더라도 상황에 맞게 동작하게 된다.


학교 다닐때 소프트웨어 공학을 수강하면서 공부한 디자인 패턴을 요즘 다시 보고 있다.
기억이 새록새록 하다.

요즘은 교제도 좋아서 재미있게 웃어 가며 마치 소설책 보듯이 봐도 이해가 쉽게 되니, 참 좋은 세상이다. 학생때는 정말 이해 되지 않았었는데...사실 그때야 프로그램을 제대로 만들지 않았으니 필요성도 못 느꼈고, 필요성을 못 느끼니 머리에 제대로 떠오르지 않아 무조건 외운 기억 밖에 없다.

UML 부터 프로그램을 시작하면 설계가 구조화 되고 좋긴한데, 이것 부터 잡고 있으면 프로그램 안하고 그림 그리기 놀이 하고 있다는 말들이 많아서...에휴....