반응형

자바 디자인 패턴 6 - Strategy

1. Strategy 패턴은..

Template Method 패턴이 상속을 이용해서 어떤 구현을 했다면, Strategy 패턴은 구성을 이용합니다. Template Method와 마찬가지로 바뀌는 부분과 바뀌지 않는 부분을 나눠서 생각할 수 있습니다. Template Method가 하위 클래스에서 바뀌는 부분을 처리한다면 Starategy는 바뀌는 부분을 인터페이스로 분리하여 처리합니다. 그 인터페이스의 구현체를 바꿈으로서 로직을 변경하는 것입니다. 또 Template Method와 크게 다른 점은 Template Method에서는 외부로 공개되는 것이 Template Method를 가지고 있는 상위 클래스였지만, Strategy에서는 인터페이스를 사용하는 클래스(그 클래스를 Context라고 합니다.)입니다.

2. 예제

------------------------ 상위 인터페이스 --------------------
package ch06_Strategy;

public interface Seller {
    public void sell();
}

------------------------- 인터페이스 구현체1 -----------------
package ch06_Strategy;

public class CupSeller implements Seller {
    public void sell() {
        System.out.println("컵을 팔아요.");
    }
}
------------------------- 인터페이스 구현체2 -----------------
package ch06_Strategy;

public class PhoneSeller implements Seller {
    public void sell() {
        System.out.println("전화기를 팔아요.");
    }
}
------------------------- 인터페이스 사용하는 클래스 -----------------
package ch06_Strategy;

public class Mart {
    private Seller seller;
    public Mart(Seller seller) {
        this.seller = seller;
    }
    public void order(){
        seller.sell();
    }
}
------------------------- 테스트 클래스 -----------------
package ch06_Strategy;

public class Test {
    public static void main(String[] args) {
        Seller cupSeller = new CupSeller();
        Seller phoneSeller = new PhoneSeller();
        Mart mart1 = new Mart(cupSeller);
        mart1.order();
        Mart mart2 = new Mart(phoneSeller);
        mart2.order();
    }
}

위에서 보시다 시피 테스트 클래스에서는 Seller의 sell()을 호출하지 않습니다. Mart의 order()를 호출합니다. Seller의 메쏘드는 외부로 공개되지 않습니다. 
Mart 클래스가 여기서는 외부로 공개되는 Context가 됩니다. Mart는 멤버 변수로 Seller를 가집니다. Mart에서 가지는 Seller를 바꿔치기함으로써 Mart의 order()에서 실제 실행되는 로직이 달라질 수 있습니다.

3. Strategy의 유용성

예제에서는 Context 클래스가 한 개의 Strategy 인터페이스만을 가집니다. Seller 외에 여러가지 인터페이스를 가질 수도 있습니다. 예를 들어 만드는 사람, 운반하는 사람, 파는 사람은 각각 다를 수 있습니다. 예제에서는 코드를 줄이기 위해 파는 사람만 2가지 종류의 클래스를 만들었습니다. 그러나, 만드는 사람 인터페이스와 운반하는 사람 인터페이스 등을 만들고 그 구현체 들을 만들면, 상당히 다양한 로직이 나올 수 있습니다. 만드는 사람의 구현체가 3종류, 운반하는 사람의 구현체가 3종류, 파는 사람의 구현체가 3종류라하면, 만들어서 운반해서 파는 로직은 총 3*3*3= 27가지가 나옵니다. 이를 상속을 이용한 클래스를 제작하면, 27가지의 구현체가 필요합니다. Strategy를 쓰면, 9개의 구현체만 필요하며, 또 인터페이스를 이용한 프로그램이 가능합니다.


4. JAVA API에 있는 Strategy

java.util.Collections 에 sort(List<T> list, Comparator<? super T> c) 라는 메쏘드가 있습니다. List를 Comparator에서 지정한 방법으로 정렬하는 메쏘드입니다. Comparator는 compare(T o1, T o2) 메쏘드 하나만 있는 인터페이스 입니다. 이 인터페이스를 구현하는 방법에 따라서 정렬된 결과가 달라집니다. "101"이 먼저일까요, "11"이 먼저일까요? 일반적인 순서에서는 "101"이 먼저입니다. 그러나 이게 숫자라면, 정렬 방법이 달라져야 합니다. Comparator를 구현함으로써 해결할 수 있습니다.

출처 : http://iilii.egloos.com/3826810


반응형

'Design Pattern' 카테고리의 다른 글

abstract factory pattern  (0) 2013.07.09
facade패턴  (0) 2013.07.05
반응형

참고 및 출처 ::

 - http://www.buggymind.com/36

 - http://pupustory.tistory.com/161



* Facade Pattern (퍼사드 패턴)

 - 어떤 서브 시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공한다.

 - 퍼사드에서 고수준의 인터페이스를 정의하기 때문에 서브 시스템을 더 쉽게 사용할 수 있다.

퍼사드 패턴은 디자인 원칙의 최소 지식 원칙을 준수하는 패턴으로써 클라이언트를 복잡한 서브 시스템과 분리시켜주는 역할을 한다. 무슨 말인고 하니, 서브 시스템을 가지고 퍼사드를 만들고 실제 작업은 서브 클래스에 맡긴다는 뜻이다.



* 예제

어항을 청소한다고 생각해보자. 먼저 물고기를 옮기고, 어항 안에 악세사리를 꺼내고, 물을 제거한 후 어항을 청소하고, 다시 악세사리를 넣고 물을 채우고 물고기를 넣는다. 이를 메소드 호출로 생각한다면 아래와 같을 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 물고기를 꺼내고
getFish();
 
// 악세사리를 꺼내고
getDecorator();
 
// 물을 비우고
getWater();
 
// 어항을 청소하고
wash();
 
// 악세사리를 설치하고
setDecorator();
 
// 물을 넣고
setWater();
 
// 물고기를 넣는다.
setFish();

이러한 어항 청소 프로세스를 하나의 메소드 또는 인터페이스로 정의한 다음 서브 시스템에서 최소한의 지식만 가지고 사용할 수 있도록 하는 것이 퍼사드 패턴이다.




* 퍼사드 패턴 적용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
doWash() {
    // 물고기를 꺼내고
    getFish();
 
    // 악세사리를 꺼내고
    getDecorator();
 
    // 물을 비우고
    getWater();
 
    // 어항을 청소하고
    wash();
 
    // 악세사리를 설치하고
    setDecorator();
 
    // 물을 넣고
    setWater();
 
    // 물고기를 넣는다.
    setFish();
}
 

물론 많은 부분이 생략되었지만 아래 다이어로그램을 참고한다면 어떤식으로 적용해야 할지 알 것이다.


실제로 퍼사드 패턴은 우리가 이미 자주 사용하고 있는 패턴 중 하나이다. 클라이언트는 캡슐화된 프로세스 내의 동작을 알 필요 없이 해당 인터페이스가 요구하는 정보만 넣어서 호출하면 원하는 결과를 얻을 수 있도록 한다. 한 마디로 복잡한 클래스들과 패키지들을 어떤 단순한 인터페이스 객체 뒤에 감추는 것이다. 


예를 들어 Java의 Date 클래스는 사실 사용하기가 좀 까다롭다. 그런 복잡한 사용 방법은 전부 다 감추고, 사용자로 하여금 단순히 '현재 날짜에 며칠을 더하면 언제가 되는지' 알려주는 인터페이스만 주고 싶다고 하자.

그러면 퍼사드 클래스를 설계해서, 그 클래스가 내부적으로 Date 클래스나 기타 관련 클래스들을 조작하게 한 다음, 퍼사드 클래스가 제공하는 인터페이스만 사용하도록 하면 된다. 결국 이렇게 해서 만들어진 퍼사드 클래스는 Date 클래스에 대한 '대안적'인 인터페이스가 되는 것이다.


따라서 퍼사드 패턴은 어떻게 보면 어댑터 패턴하고도 비슷하나 Adaptation할 기능의 규모가 좀 더 큰 경우에 보다 적합하다고도 할 수 있다.


출처 : 

http://warmz.tistory.com/764

반응형
반응형

이클립스 UML 그리기 미션!!

인디고 버젼 설명~~~~

Install New Software...  -> Indigo - http://download.eclipse.org/releases/indigo 선택!!


Modeling -> EMF, GMF SDK 설치!!
 




http://www.soyatec.com/euml2/installation/offline.php#offline
 
접속 후 버젼에 맞는(indigo) 파일 다운로드!!(eUML2 Free Edition 3.7.1.20110624 + required plugins for Indigo/Eclipse 3.7.x)

다시 install.......... -> Add -> Name 쓰시고 Archive 클릭!! 후 다운 받은 압축파일 경로로 지정



eUML2 Free Edition 설치!!!  Modeler Documentation 설치 시 오류 발생 경험............



완료~ 패키지 선택 시 아래 버튼이 활성화 되어 UML 그릴 수 있음..




출처 : http://lovelyhun.tistory.com/38

반응형

+ Recent posts