Whiteship's Note


EJ2E Item 21. 전략을 표현할 때는 함수 객체를 사용하라

Java : 2010.03.24 10:30


참조: Effective Java 2nd Edition. Item 20: Use function objects to represent strategies

자바는 함수 포인터를 제공하지 않는다. 하지만 객체 레퍼러스를 함수 객체와 비슷하게 사용할 수 있다. 

메서드를 호출하면 해당 객체에 대한 기능을 수행하는 것이고 함수 객체는 다른 객체들에서 해당 기능을 수행하게 해준다.

(사족. 메서드는 특정 객체에 종속적인 것이고, 함수 객체는 독립적으로 여러 다른 객체에서 사용할 수 있는 것으로 구분할 수 있겠다.)

함수 객체들은 Concrete Stratege 역할을 하기 때문에 보통 상태 정보가 없고(stateless), 어디서나 동일하게 동작하기 때문에 불필요한 객체 생성 비용을 줄이기 위해 싱글톤으로 사용되기 좋다.

(사족. 스프링을 사용한다면 굳이 싱글톤 구현하느라 애쓰지 말고 그냥 싱글톤 스코프 빈으로 등록하면 되겠다.)

대표적인 예로 Comparator 인터페이스 구현체들이 있다.

// Strategy interface
public interface Comparator<T> {
    public int compare(T t1, T t2);
}

이 구현체는 종종 익명 클래스로 사용되기도 한다. 하지만 익명 클래스를 사용하면 매번 새로운 인스턴스를 만들게 된다. 반복해서 사용할 꺼라면 차라리 함수 객체를 priate static final field에 저장해 놓고 재사용하는 것이 좋겠다. 그렇게 하면 명시적인 이름을 줄수도 있다.

전략이 여러개를 제공하는 "Host class"에서 외부로 공개할( public static final) strategy의 반환 타입은 Strategey 인터페이스 타입이어야 하고 구체적인 Stategy 구현체들은 굳이 public 일 필요가 없다. 

요약
- 전략 패턴을 구현할 때 함수 객체를 주로 사용한다.
- 자바에서 이 패턴을 구현할 때는 전략 인터페이스를 만들고, 각 전략들은 그 인터페이스의 구현체로 만든다.
- 만약 어떤 전략을 한번만 사용할 거면 익명 클래스로 만들고 반복해서 사용할거면 prviate static member 클래스로 만든 다음 전략 인터페이스의 public sttic final field로 제공해준다.
- 대표적인 클래스 String


top

Write a comment.


Strategy Pattern 예제(끝)

Design Pattern : 2006.10.08 11:32


Worker List Manager의 class diagram에 추가 사항.
위에서 생각해 보았던 문제가 들어맞았다...
필요없이 모양에 끼워 맞추려다가 오히려 복잡해지기만 했다.
그래서 과감히 필요없는 부분은 제거했다.

보라색 부분에 있던 sub class들을 몽땅 없애버렸다.
WorkerListManager를 사용해서도 충분히 지시된 사항들이 가능하기 때문이다.
나중에 필요하게 되면 다시 상속을 하여 사용하도록 하면 될 듯하다.
유지보수 측면을 따지자면.. 새로운 종류의 Worker들이 나타나면 소스코드가 상당히 바뀌게 된다는 문제점도 있다.. 그쪽도 어떻게든 해결을 해야 될 것 같은데.. 일단은 이상태로 제출을 해도 무관할 듯하다. 설마 교수님께서 이 글을 보시진 않으시겠지?? ㅋㅋ;;

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

3장. Decorator Pattern(계속)  (1) 2006.10.17
3장 Decorator Pattern  (0) 2006.10.17
헤드 퍼스트 새책이 나왔었네요  (2) 2006.10.17
Observe Pattern 예제(끝)  (0) 2006.10.08
Observer Pattern 예제  (0) 2006.10.08
Strategy Pattern 예제(끝)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제  (0) 2006.10.08
Head First Degisn Patterns 소스코드 다운받기.  (0) 2006.10.08
2장 Observer Pattern(끝)  (0) 2006.10.05
top

Write a comment.


Strategy Pattern 예제(계속)

Design Pattern : 2006.10.08 11:31


Worker List Manager의 class diagram 에서는 Id로 list를 관리하는 class밖에 없었기 때문에..
기본적으로 setter에서 id를 가지고 sorting을 하는 QuicjSorting이나 InsertionSorting을 사용하였습니다.
하지만 이번에는 Name으로 list를 관리하는 class가 추가 되었습니다.
이렇게 추가 되면서 이제는 setter에서 id를 가지고 Sorting을 하는 알고리즘을 injection하는 것이 아니라.. name을 가지고 Sorting하는 알고리즘을 injection해야합니다.
따라서 다음과 같이 다이어 그램이 바뀌게 됩니다.

SoringBehavior에는 기존의 Sorting들이 Id를 가지고 Sorting하였기에 ById라고 좀더 명확하게 이름을 바꿨으며 ByName의 class두개를 추가하였습니다. 그리고 NameListManager의 setSotringBehavior()에서는 InsertoinSortingByName으로 injection할 것입니다.

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

3장 Decorator Pattern  (0) 2006.10.17
헤드 퍼스트 새책이 나왔었네요  (2) 2006.10.17
Observe Pattern 예제(끝)  (0) 2006.10.08
Observer Pattern 예제  (0) 2006.10.08
Strategy Pattern 예제(끝)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제  (0) 2006.10.08
Head First Degisn Patterns 소스코드 다운받기.  (0) 2006.10.08
2장 Observer Pattern(끝)  (0) 2006.10.05
2장 Observer Pattern(계속)  (2) 2006.10.05
top

Write a comment.


Strategy Pattern 예제(계속)

Design Pattern : 2006.10.08 11:30




먼저 Worker들을 세 종류로 나누었고 바뀌는 getSalary와 display를 각각의 class에서 구현하도록 Worker class를 abstract로 선언했습니다.
그리고 녹색 부분이 Strategy Pattern 을 적용한 부분입니다.
마지막으로 최종적으로 WorkerListManager를 상속 받은 IdListManager에서 Id를 가지고 정렬하도록 sortingBehavior를 때에 따라 바꿔가며 사용할 것입니다.

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

헤드 퍼스트 새책이 나왔었네요  (2) 2006.10.17
Observe Pattern 예제(끝)  (0) 2006.10.08
Observer Pattern 예제  (0) 2006.10.08
Strategy Pattern 예제(끝)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제  (0) 2006.10.08
Head First Degisn Patterns 소스코드 다운받기.  (0) 2006.10.08
2장 Observer Pattern(끝)  (0) 2006.10.05
2장 Observer Pattern(계속)  (2) 2006.10.05
2장 Observer Pattern(계속)  (0) 2006.10.05
top

Write a comment.


Strategy Pattern 예제

Design Pattern : 2006.10.08 11:22


Strategy Pattern을 이용한 사원 List 관리

사원의 List를 관리하는 프로그램을 작성합니다.
기존의 legacy system에서 사용하던 사원의 data는 txt파일 형태로 존재 합니다. 예를 들어 모든 data는 id, name, salary, commission, hourOfWorked, payPerHour 순으로 입력이 되어 있으며 사원의 종류에 따라 어떤 직원은 salary만 기입되어 있는 data도 있으며 salary와 commission만 기입되어 있는 data도 있고 hourOfWorked와 payPerHour만 기입되어 있는 사원이 있습니다. 즉 어떤 사원은 월급을 계산할 때 salary만 주면 되는 것이고 어떤 사원은 salary +commission을 주고 어떤 사원은 시급 * 일한 시간을 계산하여 월급을 계산합니다. 그리고 직원들은 현재 무작위순입니다.
위 txt파일로부터 직원들의 정보를 읽어 들여서 새로운 웹기반의 시스템에서 사용하려고 합니다. 이 직원들의 List를 관리하는 프로그램을 사용하여 직원들을 id또는 이름순으로 정렬하고자 합니다. 정렬 할 때 맨 처음 무작위 순으로 되어 있는 경우는 Quick Sorting이나 Merge Sorting을 사용하는 것이 효율적입니다. 하지만 새로운 직원이 List에 추가 되거나 삭제 될 때는 Insertion Sorting을 사용하는 것도 효율적입니다. 여기서 다시 이름순으로 정렬을 할 때는 기존의 data들이 id순으로 정렬되어 있기 때문에 이름순으로 따진다면 무작위순으로 되어 있는 것과 마찬가지입니다. 따라서 다시 Quick Sorting이나 Merge Sorting을 사용하여 Sorting을 하고 다시 새로운 직원을 추가하거나 삭제 할 때는 Insertion Sorting을 사용할 수 있습니다.

위 상황에 적합하도록 Class들을 구현하여(Design이 보통 선행 될 것입니다.) test class를 작성하여 test해 봅시다.

요약


1. txt 파일로부터 data를 읽어 들여 월급 정보에 따라 직원들의 type에 맞는 객체를 생성하여 List에 추가할 것.
2. List를 Id 순 또는 Name 순으로 최초 정렬을 할 것.(이 때는 Quick Sorting or Merge Sorting사용.)
3. 새로운 직원을 생성하여 List에 추가할 할 것.(이 때는 Insertion Sorting을 사용할 것.)
4. 2번에서 Id로 정렬하였다면 이번에는 Name으로 정렬하도록 합시다.(Name으로 정렬하는 List 관리자로 대체 하면 될 것입니다.)
5. 다시 최초 정렬을 하고.
6. 새로운 직원을 생성하여 추가합니다.

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

Observe Pattern 예제(끝)  (0) 2006.10.08
Observer Pattern 예제  (0) 2006.10.08
Strategy Pattern 예제(끝)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제  (0) 2006.10.08
Head First Degisn Patterns 소스코드 다운받기.  (0) 2006.10.08
2장 Observer Pattern(끝)  (0) 2006.10.05
2장 Observer Pattern(계속)  (2) 2006.10.05
2장 Observer Pattern(계속)  (0) 2006.10.05
2장 Observer Pattern  (0) 2006.10.05
top

Write a comment.


1장 Strategy Pattern (끝)

Design Pattern : 2006.09.26 00:23


최종적으로 위와 같은 다이어그램이 완성됩니다.
상속으로 시작했던 디자인이 composition(구성)을 사용함으로써 결말이 났군요.
이로써 다음과 같은 디자인 원칙을 배울 수 있습니다.
디자인 원칙3
상속보다는 구성을 활용한다.
위에서 했던 행동들이 하나의 디자인 패턴으로 정립되어 있었습니다.
바로 Strategy pattern 이라는 것으로 써 정의는 다음과 같습니다.
Strategy Pattern에서는 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있돌고 만든다. 이것을 사용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.
위키피디아 에서 정의한 내용은 다음과 같습니다.

Strategy pattern

From Wikipedia, the free encyclopedia

Jump to: navigation, search
In computer programming, the strategy pattern is a particular software design pattern, whereby algorithms can be selected on-the-fly at runtime.
In some programming languages, such as those without polymorphism, the issues addressed by this pattern are handled through forms of reflection, such as the native function pointer or function delegate syntax.
The strategy pattern is useful for situations where it is necessary to dynamically swap the algorithms used in an application. The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. The strategy pattern lets the algorithms vary independently from clients that use them.
runtime시에 알고리즘을 선택할 수 있는 특징이 있고 다형성이 지원되지 않는 언어의 경우 포인터와 delegate syntax와 같은 reflection의 형태로 다뤄집며 유용한 상황으로는 동적으로 알고리즘을 바꾸고 싶을 경우라고 간략히 요약할 수 있습니다.
원문은 위의 링크와 같으며 예제로 여러가지 sorting 알고리즘을 동적으로 바꿔가며 사용해보는 예제가 C++언어로 나와있습니다.
더 구체적인 내용은 이곳에서 볼 수 있습니다.
decoupling에 관한 내용과 여러 장점에 대해 설명이 되어 있습니다.
다음은 기본 Strategy Pattern의 기본 UML입니다.
마지막으로 실생활에 Strategy Pattren을 적용한 예를 살펴보겠습니다.

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

Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제  (0) 2006.10.08
Head First Degisn Patterns 소스코드 다운받기.  (0) 2006.10.08
2장 Observer Pattern(끝)  (0) 2006.10.05
2장 Observer Pattern(계속)  (2) 2006.10.05
2장 Observer Pattern(계속)  (0) 2006.10.05
2장 Observer Pattern  (0) 2006.10.05
1장 Strategy Pattern (끝)  (0) 2006.09.26
1장 Strategy Pattern(계속)  (2) 2006.09.26
1장 Strategy Pattern  (0) 2006.09.26
top

Write a comment.


1장 Strategy Pattern(계속)

Design Pattern : 2006.09.26 00:20


이전 글에서 발생했던 문제를 해결하기 위해서 interface를 사용하여 날아다닐 수 있는 오리와 소리낼 수 있는 오리로 구분하였습니다.
날아 다니거나 소리 낼 수 있는 오리들은 해당 interface를 구현해야 하며 따라서 fly나 quack과 같은 method들을 구현해 주어야 합니다.
만약에 이런 상황에서 오리의 소리가 공통적으로 바뀐다면 어떻게 해야할까요? 아마 Quackable을 구현한 모든 class들을 수정해야 할 것입니다.
(현재는 class들의 수가 몇개 안되지만 50개 라고 하면 50번을 수정해야 합니다.)
좀더 좋은 방법이 필요할 듯합니다.
지금까지 계속 변화를 가정하여 class들이 보다 유연하게 구성되도록 진행되가고 있습니다.(그만큼 변화가 빈번히 일어난다는 것이겠죠.)
이러한 변화 속에서 살아남으려면 다음과 같은 디자인 원칙에 유의해야합니다.
디자인원칙1
애플리케이션에서 달라지는 부분을 찾아 내고, 달라지지 않는 부분으로부터 분리시킨다.
즉 fly()와 quack()은 Duck class에서 오리마다 달라지는 부분입니다.
이 두 메소드를 Duck에서 뽑아 내어 새로운 class집합으로 만들 것입니다.
이 class집합들은 다음의 디자인 원칙에 따라 구현합니다.
디자인원칙2
구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
이 말은 선뜻 이해가 되지 않습니다.
여기서 구현이라고 하는 것은 특정 class에 있는 method를 말하는 것이고 인터페이스는 상위 classl에 있는 method들을 말한다고 생각합니다.
즉.. Animal a = new Dog(); or new Cat();
a.eat();
을 실행했을 때 개도 먹일 수 있고 고양이도 먹일 수 있도록 프로그래밍 하라는 뜻으로 이해가 됩니다.
(저 방법 보다 Animal a = getAnimal(); 이런 방법으로 new 키워드를 없애는 것이 보다 더 디자인원칙2를 잘 지키는 것이라고 나와있습니다.)
따라서 다음과 같은 다이어 그램으로 class집합을 구현할 수 있습니다.

이제 Duck class에서는 위 두 집합의 상위Type의 변수를 가진다면 a.eat()과 같은 장점(다형성)을 누릴 수 있습니다.
위와 같이 FlyBehavior와 QuackBehavior type의 변수를 가지고 있고
performFly()와 performQuack()에서는
flyBehavior.fly()와 quackBehavior.quack()를 실행하기만 하면 됩니다.
이렇게 해두면 각각의 오리( sub class )들은 dispaly()만 구현하면 되고 자기 자신의 quack이나 fly의 Behavior가 어떤 것인지 설정해 줌에 따라 결과가 달라지게 됩니다.
자신의 Behavior를 설정하는 방법은 객체 생성시에 생성자에서 하는 방법과
나중에 setter메소드를 사용하는 방법이 있습니다.
setter메소드를 이용하여 Behavior를 지정해 줄 경우 날수 없던 오리(FlyNoWay Behavior로 setting했던 오리)가 갑자기 날개를 가지고 날아갈 수있게(FlyWithWings Behavior로 오리의 Behavior를 프로그램 실행도중 setter method를 사용하여 setting하면 됩니다.) 마술을 부릴 수도 있습니다.

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

Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제  (0) 2006.10.08
Head First Degisn Patterns 소스코드 다운받기.  (0) 2006.10.08
2장 Observer Pattern(끝)  (0) 2006.10.05
2장 Observer Pattern(계속)  (2) 2006.10.05
2장 Observer Pattern(계속)  (0) 2006.10.05
2장 Observer Pattern  (0) 2006.10.05
1장 Strategy Pattern (끝)  (0) 2006.09.26
1장 Strategy Pattern(계속)  (2) 2006.09.26
1장 Strategy Pattern  (0) 2006.09.26
top

  1. thank you 2007.04.02 13:57 PERM. MOD/DEL REPLY

    좋은글 감사합니다.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.04.02 14:50 신고 PERM MOD/DEL

    넵 방문 감사합니다. :)

Write a comment.


1장 Strategy Pattern

Design Pattern : 2006.09.26 00:17




위 다이어그램을 보면 Duck class를 상속을 이용하여 재사용 하고 있습니다.
필요한 부분( 여기서는 display() )만 overriding 해주면 되기 때문에 상당히 편리해 보입니다.
기본 기능으로 오리가 날수 있도록 하고 싶을 때...



위와 같이 상위 class에 추가하기만 하면 모든 하위 class들에 일일히 추가할 필요가 없기때문에 편리해 보입니다.
하지만...
날지 못하는 오리(고무 인형 오리)의 경우라면 상속 받지 말아야 할텐데.
특정 method를 제외하고 상속하는 방법 같은 것은 배운적이 없네요 :)
상속을 못하게 하는 방법은 있지만 그렇게 하면 다른 자식 class들은 어떻게 하나요? 하핫;
method하나가지고 뭘 그러나.. 그냥 method를 overring해서 안에서 아무것도 안하면 되지 않을까...라는 생각을 처음엔 했었습니다.
그러나...
그러한 method가 무진장 많다고 했을 때를 생각해 보면 코드 낭비에 시간 낭비라는 생각이 안들 수가 없습니다. 무언가 뾰족한 수가 필요합니다.

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

Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제(계속)  (0) 2006.10.08
Strategy Pattern 예제  (0) 2006.10.08
Head First Degisn Patterns 소스코드 다운받기.  (0) 2006.10.08
2장 Observer Pattern(끝)  (0) 2006.10.05
2장 Observer Pattern(계속)  (2) 2006.10.05
2장 Observer Pattern(계속)  (0) 2006.10.05
2장 Observer Pattern  (0) 2006.10.05
1장 Strategy Pattern (끝)  (0) 2006.09.26
1장 Strategy Pattern(계속)  (2) 2006.09.26
1장 Strategy Pattern  (0) 2006.09.26
top

Write a comment.