생성(Creational) 패턴 - Singleton

2007/05/19 12:52
Singleton 패턴은 Creational 패턴들과 같은 그룹에 속하지만, "non-creational" 패턴의 확장적인 면이 있음. 프로그래밍에서 클래스의 인스턴스를 하나만을 갖게 해야 할 경우에 사용.

1. 의도
클래스에서 만들 수 잇는 인스턴스가 오직 하나여야 하고, 이 오브젝트에 대한 접근은 어디에서든지 항상 동일한 방법으로 접근 할 수 잇도록 제공.

2. 고려해야 할 사항
  • 어떤 클래스는 단 하나의 인스턴만 생성되어야 함.
  • 단 하나의 인스턴스는 언제든지 사용할 수 있어야 함.
  • 클래스를 이용해 생성된 하나의 인스턴스는 모든 클라이언트가 쉽게 억세스 할 수 있어야함.
3. 구조
사용자 삽입 이미지

ThreadPool.java (Language : java)
  1. public class ThreadPool {
  2.    private ThreadPool singleInstance;
  3.  
  4.    private ThreadPool() {}
  5.  
  6.    public static TreadPool getInstance() {
  7.       if (singleInstance == null) {
  8.          singleInstance = new ThreadPool();
  9.       }
  10.       return singleInstance;
  11.    }
  12.  
  13.    public Thread getThread() {
  14.       // ...
  15.       return thread;
  16.    }
  17. }

Client.java (Language : java)
  1. public class Client {
  2.    public static void main(String[] args) {
  3.       ThreadPool threadPool = ThreadPool.getInstance();
  4.       Thread t = threadPool.getThread();
  5.    }
  6. }

4. 자바 프로그래밍 언어에서의 사용 예
  • Java API중 java.lang.Runtime 클래스가 Sigleton 클래스를 사용
5. 결론
  • 장점
    클라이언트는 쉽게 싱글 오브젝트 레퍼런스를 얻을 수 있음.
    Singleton은 클래스 로딩 타임 또는 클라이언트가 객체 생성을 요청했을 때 인스턴스를 생성할 수 있음.
    Singleton 클래스의 인스턴스가 하나 이상 존재해야 하는 경우 이 변경작업이 쉬움. 즉, Singleton 클래스의 인스턴스에 접근할 수 있는 허용 범위를 결정하는 오퍼레이션만 변경하면 됨. 왜냐하면 기존에는 하나의 인스턴스로만 접근을 허용했다면, 이제는 여러 개의 인스턴스를 생성해서 그 각각의 인스턴스로 접근 할 수 잇도록 오퍼레이션의 구현을 바꾸면 됨.
  • 단점
    Singleton은 전역변수의 용도록 사용될 수 잇음. 그러나 이 방법은 종종 잘못 적용되는 경우가 많음.
    Singleton은 여러 클라이언트가 동시에 인스턴스를 생성해달라고 요청할 때에도 단 하나의 인스턴스만 생성되도록 제어해야 함.

이올린에 북마크하기

happyness Programming/J2EE Patterns , ,

2007/05/19 12:52 2007/05/19 12:52
  1. 싱글톤을 적용하여 웹 프로젝트에서 어떤 작업에 적용 할 수 있는지 궁금한데요
    lsv400@naver.com 부탁 드립니다.

[로그인][오픈아이디란?]

행위(Behavioral) 패턴 - Observer

2007/05/11 20:50

1.의도
한 객체의 상태가 변경되면 그것을 관찰하는 다른 여러 객체들에게 그 사실이 전달되어 자동으로 특정 기능이 수행되도록 하는데 그 목적이 있음.

2. 고려해야 할 사항

  • 상태 체크를 위해 오브젝트를 계속 폴링하는 것은 메모리와 CPU를 낭비하는 것임.
  • 하나의 오브젝트를 여러 개의 오브젝트가 질의할 경우 동기화 문제를 고려해야 함.
  • 어떤 상태 변경 시 이를 통보하기 위해 Observable 오젝트는 Observer 오브젝트를 알아야함.
  • Observable 오브젝트는 Observer 오브젝트 타입과 커플링이 존재하지 말아야 함.

3. 구조

사용자 삽입 이미지


FaultMessageGenerator.java (Language : java)
  1. import java.util.*;
  2. public class FaultMessageGenerator {
  3.    private ArrayList listeners = new ArrayList();
  4.  
  5.    public void addFaultListener(FaultListener listener) {
  6.       listers.add(listener);
  7.    }
  8.  
  9.    public void faultOccurred(int faultType, String faultMsg) {
  10.       Iterator listenrsl = listeners.iterator();
  11.       while (listenersl.hasNext()) {
  12.          FaultListener fl = (FaultListener)listenersl.next();
  13.          fi.handleFault(faultType, faultMsg);
  14.       }
  15.    }
  16.  
  17.    public void removeFaultListener(FaultListener listener) {
  18.       listeners.remove(listener);
  19.    }
  20. }

FaultListener.java (Language : java)
  1. public interface FaultListener {
  2.    public void handleFault(int faultType, String faultMsg);
  3. }

FaultLogger.java (Language : java)
  1. import java.util.logging.*;
  2.  
  3. public class FaultLogger implements FaultListener {
  4.    private static Logger logger = Logger.getLogger("");
  5.  
  6.    public FaultLogger(faultMessageGenerator fmg) {
  7.       fmg.addFaultListener(this);
  8.    }
  9.  
  10.    public void handleFault(int faultType, String faultMsg) {
  11.       logger.log(Level.WARNING, "A" + faultType + " occured: " + faultMsg);
  12.    }
  13. }

FaultTester.java (Language : java)
  1. public class FaultTester {
  2.    public static void main(String args[]) {
  3.       FaulltMessageGenerator fmg = new FaultMessageGenerator();
  4.       new FaultLogger(fmg);
  5.       new FaultPager(fmg);
  6.       new FaultEMailer(fmg);
  7.       fmg.faultOccured(72, "Lost customer data: Peters, V.");
  8.    }
  9. }


4. 자바 프로그래밍 언어에서의 사용 예


사용자 삽입 이미지

  • JDK™ 1.4에서부터 제공되고 있는 java.util.logging 패키지에서 제공하는 새로운 logging API에서 사용됨.
  • 메시지를 기록하기 위해, 클라이언트는 Logger 클래스가 제공하는 log 메소드를 호출, 클라이언트는 메시지를 파일, 콘솔 또는 소켓과 같은 다른 위치에 기록되기를 원할 수 있음. 메시지가 기록된 위치는 Handler 추상클래스의 서브클래스로 구현.
  • Handler 클래스는 Logger 클래스의 관찰자임. Logger 오브젝트상의 log 메소드가 호출될 때 Logger 오브젝트에 추가되어 있는 Handler의 publish 메소드를 호출
  • 이 어플리케이션과 Observer 패턴과의 한가지 차이점은 Logger 클래스가 Observer 기능을 가지고 있지 않음

5. 결과

  • 장점
    Subject와 Observer 오브젝트를 위한 클래스는 독립적인 형태로 재사용 가능.
    추상클래스(또는 인터페이스)가 서로 결합되어 있음. 따라서 콘크리트 클래스가 커플링이 존재하는 것보다 커플링이 더 느슨함.
    Subject 오브젝트를 변경시키지 않으면서 Observer 오브젝트를 쉽게 추가할 수 있음.
  • 단점
    Observer 시스템은 변경의 정도가 너무 정교하거나 너무 자주 발생할 경우 변경작업이 너무 자주 일어나게 됨. 이것은 분산 환경에서 매우 심각한 문제가 됨.
    Observer 시스템은 통보를 받았을 때 자주 Subject를 호출, 이것은 병목현상을 발생시킬 수 있음


이올린에 북마크하기

happyness Programming/J2EE Patterns , ,

2007/05/11 20:50 2007/05/11 20:50
[로그인][오픈아이디란?]

행위(Behavioral) 패턴 - Iterator

2007/05/09 23:43
Iterator 는 디자인 패턴에서 가장 간단하고 가장 빈번하게 사용되는 패턴들 중의 하나.  Iterator 패턴은 데이터의 내부적인 표현을 자세하게 아는 것 없이 표준적인 인터페이스를 이용한 데이터의 리스트나 컬렉션을 통하여 이동하는 것을 허용. 게다가 어떤 특별한 프로세싱과 데이터 컬렉션의 특정한 원소를 반환을 하는 특별한 Iterator를 정의할 수 있음.

1. 동기
Iterator는 어떻게 Iterator가 데이터를 이동시키는지를 드러내지 않고 데이터 원소들의 집합을 통하여 이동하는 정의된 Iterator는 인터페이스(interface)이기 때문에 반환되는 데이터를 위한 편리한 어떤 방법이든 구현

2. 고려해야 할 사항
컬렉션 또는 데이터 소스는 보통 클라이언트가 데이터를 조작할 수 있는 방법을 제공해야 함. 그러나, 컬렉션 또는 데이터 소스에 직접 데이터 조작 로직을 놓는 것은 항상 바람직하지 않음.
이 문제를 해결하기 위해 다음과 같은 사항에 유의.
  • 호출자가 컬렉션을 억세스하기 위한 로직을 직접 사용할 경우 불필요하게 작업이 복잡해지고 컬렉션에 강하게 결합되는 문제가 발생
  • 컬렉션에 존재하는 데이터 요소들을 접근하는 것은 시간을 낭비하지 않으면서 쉬워야 함
  • 다른 종류의 컬렉션들을 항상 같은 방법으로 접근할 수 있어야 함

3. 구조

사용자 삽입 이미지

CatalogIterator.java (Language : java)
  1. public interface CatalogIterator {
  2.  public boolean hasMoreElements();
  3.  public Object nextElement();
  4.  public Object currentElement();
  5.  public Object previousElement();
  6. }

ResultSetIterator.java (Language : java)
  1. public class ResultSetIterator implements CatalogIterator {
  2.  private CaltalogDataSource ds
  3.  private int index;
  4.  
  5.  public ResultSetIterator(CatalogDataSource ds) {
  6.   this.ds = ds;
  7.   this.index = index;
  8.  }
  9.  
  10.  public boolean hasMoreElements() {
  11.   if (index < ds.getLength()) return true;
  12.   else return false;
  13.  }
  14.  
  15.  public Object nextElement() {
  16.   Object result = ds.getNextResult(index);
  17.   index++;
  18.   return result;
  19.  }
  20.  
  21.  public Object currentElement() {
  22.   return null;
  23.  }
  24.  
  25.  public Object previousElement() {
  26.   return null;
  27.  }
  28. }

CatalogDataSource.jva (Language : java)
  1. public interface CatalogDataSource {
  2.  public CatalogIterator iterator();
  3.  public int getLength();
  4.  public Object getNextResult(int index);
  5.  public void appendResult(Object result);
  6. }

ResultSetWrapper.java (Language : java)
  1. public class ResultSetWrapper inplements CatalogDataSource {
  2.    private Object[] results;
  3.    private int last;
  4.  
  5.    public CatalogIterator iterater() {
  6.       return new ResultSetIterator(this);
  7.    }
  8.  
  9.    public int getLength() {
  10.       return last;
  11.    }
  12.  
  13.    public Object getNextResult(int index) {
  14.       return results[index];
  15.    }
  16.  
  17.    public void appendResult(Object result) {
  18.       this.results[last] = result;
  19.       last++;
  20.    }
  21. }

Client.java (Language : java)
  1. public class Client {
  2.    public static void main(String[] args) {
  3.       ResultSetWrapper results = new ResultSetWrapper(3);
  4.       results.appendResult(new Integer(10));
  5.       results.appendResult("hello");
  6.       results.appendResult(new java.util.Data());
  7.  
  8.       CatalogIterator it = results.iterator();
  9.       while(it.hasMoreElements()) {
  10.          System.out.println(it.nextElement());
  11.       }
  12.    }
  13. }

4. 자바 프로그램언어에서의 사용 예
사용자 삽입 이미지
  • J2SETM 플랫폼에서의 java.util 패키지에 존재하는 컬렉션에서 Iterator 패턴을 사용.
  • Collection 인터페이스는 클라이언트가 Iterator 서브타입의 객체를 사용할수 있도록 iterator 메소드를 제공.
  • List 인터페이스는 클라이언트가 ListIterator 서브타입의 객체를 사용할 수 있도록 listIterator 메소드를 정의. ListIterator 메소드는 Iterator 인터페이스보다 데이터 접근을 위한 좀더 많은 메소드를 정의.
  • Iterator와 ListIterator 서브타입을 사용함으로써, 클라이언트는 일반적인 데이터 접근코드를 이용해 Collection 또는 List 서브타입을 액세스. 

5. 결과

  • 장점
    억세스 관련 메소드를 정의하지 않음으로써 collection interface가 좀더 간단해짐
    컬렉션 종류와 상관없이 동일한 방업을 컬렉션에 존재하는 요소들을 억세스할 수 있음
    같은 컬렉션에 대해 다른 억세스 알고리즘을 지원
    동시에 억세스 할 수 있도록 지원
  • 단점
    런타임에 오브젝트가 추가적으로 생성
    쓰레드 환경에서 iterator를 통해 테이터를 억세스 하는 경우 다른 iterator가 접근할 수 없도록 설계해야 함
이올린에 북마크하기

happyness Programming/J2EE Patterns , ,

2007/05/09 23:43 2007/05/09 23:43
[로그인][오픈아이디란?]

행위(Behavioral) 패턴 - Command

2007/05/06 20:58

Chain of Responsibility 패턴은 클래스들의 체인들을 따라서 요청들을 진행하지만, Command 패턴은 특별한 모듈로 하나의 요청을 진행. 그것은 하나의 객체 내부의 특정한 동작을 위한 하나의 요청을 둘러싸고 알려진 public 인터페이스를 줌. 그것이 수행하게 될 실제적인 동작에 대한 알고 있는 것 없이 요청들을 만들 수 있는 능력을 클라이언트에게 주게 함. 그리고 어떤 방식으로든 클라이언트 프로그램에 영향을 주는 것 없이 동작을 변경할 수 있도록 해야함.

1. 동기
명령과 요청 자체를 객체 안에 캡슐화하여 포함시킬 수 있음. 그러면 이 명령 객체를 받은 클라이언트 객체들은 명령의 내용에 따라 각기 다르게 행동할 수 있으며 명령들을 큐에 저장하거나 로그에 기혹하여 나중에 사용할 수 있음. 또한 명령을 수행하기 이전 상태로 복원(undo)할 수 있음

2. 고려해야 할 사항

  • 다이나믹하게 새로운 액션을 추가하고 기존 액션을 수정하는 작업이 쉬워야 함.
  • 클라이언트가 요청해야 할 수 있는 많은 액션들이 존재하지만 클라이언트가 요청하는 방법은 간단해야 함.
  • 클라이언트는 자신의 요청이 어떻게 핸들링 되는지에 대하여 몰라야 함.
  • 클라이언트가 요청하기 위해 사용할 인터페이스는 간단해야 함.
  • 이전에 수행된 액션들을 원 상태로 되돌리거나 다시 수행하기 위해 수행했던 액션들에 대한 기록을 유지.

3. 구조

사용자 삽입 이미지

Client.java (Language : java)
  1. public class Client {
  2.    public static void main(String[] args) {
  3.       Command checkOut = new CheckOutCommand();
  4.       LibraryCommandInvoker invoker = new LibraryCommandInvoker();
  5.       invoker.executeCommand(checkOut);
  6.       invoker.redoNextCommand();
  7.       invoker.undoLastCommand();
  8.    }
  9. }
LibraryCommandInvoker.java (Language : java)
  1. public class LibraryCommandInvoker {
  2.    private int lastCommand;
  3.    private ArrayList history = new ArrayList();
  4.    
  5.    public void executeCommand(Command lc) {
  6.       lc.execute();
  7.       history.add(lc);
  8.       lastCommand = history.size() - 1;
  9.       System.out.println("execute =>" + lastCommand);
  10.    }
  11.    
  12.    public void redoNextCommand() {
  13.       System.out.println("redo =>" + lastCommand + " " + history.size());
  14.       if (lastCommand < history.size()) {
  15.          ((Command)(history.get(lastCommand))).execute();
  16.          history.add(history.get(lastCommand));
  17.          lastCommand++;
  18.       }
  19.    }
  20.    
  21.    public void undoLastCommand() {
  22.       System.out.println("undo =>" + lastCommand);
  23.       ((Command)(history.get(lastCommand))).undo();
  24.       history.remove(lastCommand);
  25.       lastCommand--;
  26.    }
  27. }
Command.java (Language : java)
  1. public interface Command {
  2.    public void execute();
  3.    public void undo();
  4. }
CheckOutCommand.java (Language : java)
  1. public class CheckOutCommand implements Command {
  2.    public void execute() {
  3.       System.out.println("execute check out command");
  4.    }
  5.    
  6.    public void undo() {
  7.       System.out.println("cancel check out command");
  8.    }
  9. }


4. 자바 프로그래밍 언어에서의 사용 예

사용자 삽입 이미지

  • GoF Command 패터는 Apache Struts 웹 어플리케이션 프레임웍과 같은 다양한 엔터프라이 프레임 웍에서 사용됨.
  • Floyd Marinescu가 쓴 EJB Design Patterns라는 책에서는 Command 패턴을 EJB Command 패턴이라고 문서화하고 있음.
  • EJB Command 패턴은 클라이언트와 EJB 레이어간 결합도를 줄임으로써 비즈니스 로직 변경으로 인한 개발 프로세스를 단순화시키기 위한 방법을 제공.
  • GoF Command 패턴과 EJB Command 패턴의 주요 차이점은 EJB Command 패턴에서 Invoker 클래스가 stateless 세션 빈임.

5. 결과

  • 장점
    케이스 로직을 줄일 수 있음.
    확장(extensibility)이 용이.
    명령어 취소(undo) 오퍼레이션을 쉽게 제공할 수 있음.
    여러 개의 명령어를 큐에 놓음으로써 명령을 비동기적으로 수행할 수 있음.
  • 단점
    객체 생성, 파괴, 사용에 있어서 많은 오버헤드가 발생할 수 있음.
    어플리케이션의 구조가 더 복작해 짐.
이올린에 북마크하기

happyness Programming/J2EE Patterns , ,

2007/05/06 20:58 2007/05/06 20:58
[로그인][오픈아이디란?]

행위(Behavioral) 패턴 - Strategy

2007/05/04 22:44
다양한 알고리즘이 존재하면 이들 각각을 하나의 클래스로 캡슐화하여 알고리즘의 대체가 가능하도록 함. Strategy 패턴을 이용하면 클라이언트와 독립적인 다양한 알고리즘으로 변형할 수 있음. 알고리즘을 바꾸더라도 클라이언트는 아무런 변경이 필요 없음.

1. 동기
특별한 서비스나 기능을 요구하는 프로그램과 기능을 수행하는 여러 가지 방법을 가지고 있는 것은 Strategy 패턴의 후보. 프로그램들은 컴퓨터 효율이나 사용자 선택을 기준으로 알고리즘을 선택.
 우리가 여러 가지 다른 방법으로 같은 일을 하려고 하는 프로그램에서 다수의 경우가 존재.
  • 다른 포멧으로 파일들을 저장.
  • 다른 알고리즘을 사용하여 파일들을 압축
  • 다른 압축 구조를 이용하여 비디오 데이터를 캡쳐.
  • 텍스트 데이터를 나타내기 위한 다른 line-breaking 전략을 이용.
  • 같은 데이터를 다른 포멧으로 그린다 : 선 그래프, 막대 그래프 나 파이 차트

2. 고려해야 할 사항

  • 클래스들은 종종 여러개의 알고리즘 선택이 필요
  • 알고리즘이 어떤 방법으로 구현되어 있는 지와 같은 구체적인 정보가 클라이언트 클래스에 노출되지 말아햐 함
  • 많은 조건문을 이용해 구현되어 있는 알고리즘은 관리가 어려움

3. 구조

사용자 삽입 이미지


SortUseCase.java (Language : java)
  1. public class SortUseCase {
  2.  public static void main(String[] args) {
  3.   strategySort sSort = new strategySort();
  4.   QuickSortAlgorithm qSort = new QuickSortAlgorithm();
  5.   sSort.SetAlgorithm(qSort);
  6.   sSort.Sort();
  7.  }
  8. }

strategySort.java (Language : java)
  1. public class strategySort {
  2.  
  3.  strategySort(){}
  4.  
  5.  void Sort(){
  6.   mSort.Sort();
  7.  }
  8.  void SetAlgorithm( SortAlgorithm sort ){
  9.   mSort = sort;
  10.  }
  11.  
  12.  SortAlgorithm mSort;
  13.  private SortAlgorithm sortAlgorithm = null;
  14.  public SortAlgorithm getSortAlgorithm() {
  15.   return sortAlgorithm;
  16.  }
  17.  public void setSortAlgorithm(SortAlgorithm sortAlgorithm) {
  18.   this.sortAlgorithm = sortAlgorithm;
  19.  }
  20. }

SortAlgorithm.java (Language : java)
  1. public interface SortAlgorithm {
  2.  void Sort();
  3.  public strategySort strategySort = null;
  4. }

BinarySortAlgorithm.java (Language : java)
  1. public class BinarySortAlgorithm implements SortAlgorithm {
  2.  public void Sort(){
  3.   System.out.println("Binary Sort");
  4.  }
  5. }


BubbleSortAlgorithm.java (Language : java)
  1. public class BubbleSortAlgorithm implements SortAlgorithm{
  2.  public void Sort(){
  3.   System.out.println("Bubble Sort");
  4.  }
  5. }


QuickSortAlgorithm.java (Language : java)
  1. public class QuickSortAlgorithm implements SortAlgorithm {
  2.  
  3.  public void Sort(){
  4.   System.out.println("Quick Sort");
  5.  }
  6. }

4. 자바 프로그래밍 언어에서의 사용 예

사용자 삽입 이미지

  • J2SE™ 플랫폼의 java.awt 패키지에서 사용
    AWT의 GUI 컨테이너는 grid, border, flow 등과 같은 레이아웃으로 구성되어 있으며, AWT는 모든 GUI 컨테어너에 할당되어 있는 레이아웃 메니져를 통해 이 메커니즘을 제공
  • 컨테이너는 콤포넌트를 배치하는 작업을 레이아웃 매니져에게 위임하고 있음.

5. 결과

  • 장점
    조건절을 사용하지 않고 여래개의 알고리즘 구현이 가능
    위임(Delegatetion)이라는 느슨한 연결을 사용하고 있기 때문에 기존 알고리즘을 변경 및 새로운 알고리즘 추가가 용이
  • 단점
    클라이언트는 전략 선택을 위해 어떤 전략들이 존재하는지 알고 있어야 함
    오브젝트와 메소트 호출 증가로 오버헤드가 조금 증가할 수 있음.
    오브젝트 수가 증가
이올린에 북마크하기

happyness Programming/J2EE Patterns , ,

2007/05/04 22:44 2007/05/04 22:44
[로그인][오픈아이디란?]

행위(Behavioral) 패턴

2007/05/03 23:01

1. 정의 및 특성

  1. 정의 : 행위(Behavioral) 패턴은 객체나 클래스에 대한 패턴을 정의하는 것이 아니고 그들 간의 교류방법에 대하여 정의하는 것으로, 애플리케이션에 따라서 행의가 다른 객체로 옮겨가거나 알고리즘이 대체되는 경우, 이런한 변화의 개념을 만족할 수 있음.
  2. 특성 :
    알고리즘과 클래스간 책임(responsibility)의 분산에 초점을 맞추고 있음.
    시스템의 정적인 구조보다는 오브젝트간 상호동작에 초점을 맞추고 있음.
  3. 알고리즘 구현과 제어 흐름을 분리시킴

2. 종류

  1. Strategy Pattern : 클래스 내에 관련 알고리즘이 캪슐화 되어 있고 이 알고리즘은 필요에 따라 교환이 가능
  2. Command Pattern : 오브젝트 내에 명령들이 캡슐화 되어 있어, 이들 명령의 선택, 실행순소, 명령취소 등을 제어할 수 있음.
  3. Iterator Pattern : 컬렉션 내에 존재하는 오브젝트틀의 구현 형태와 상관없이 동일한 방법으로 억세스할 수 있음.
  4. Observer Pattern : 폴링(polling)작업을 수행하지 않으면서 관찰 대상의 상태 변경시 관찰자에게 통지.
이올린에 북마크하기

happyness Programming/J2EE Patterns ,

2007/05/03 23:01 2007/05/03 23:01
[로그인][오픈아이디란?]