Ace-T's Blog 내 검색 [네이버 커넥트 이웃 합니다~^-^/ 요청 大 환영~~]

[DesignPattern] Decorator Pattern

Architecture/DesignPattern 2014.01.27 09:28
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T

Decorator Pattern


 개요

 클래스 다이어그램

 예제(Java)

 같이보기

 참고 사항


<< 개요 >>

Decorator Pattern 이란?

 

데코레이터 패턴(Decorator pattern)이란 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안이 될 수 있다.

(출처 : 위키피디아 - http://ko.wikipedia.org/wiki/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0_%ED%8C%A8%ED%84%B4)

 

의도

객체에 동적으로 새로운 서비스를 추가

기능 추가를 위해 서브클래스를 생성 하는 것 보다 융통성이 있음.

 

 

아래의 로봇 사진 출처 : http://blog.naver.com/PostView.nhn?blogId=romantico_q&logNo=50185115988

 

변신 합체 로봇!! 페가서스 라고 하네요^^;;

데코레이터 패턴을 학습 하면서 기억에 많이 남을만한 예제가 없을까? 라고 생각하던 차에..변신합체 로봇을 통해 학습하면 좋겠다고 생각하게 되었습니다..ㅋㅋㅋㅋ;;

 

우리의 변신합체 로봇들을 소개 합니다.

우리의 메인 로봇인 왼쪽 - 파랭이 로봇!!

그 외 몸통이 될 가운데 로봇, 다리가 되어줄 빨갱이 로봇ㅋㅋ

 

하일라이트로 다시 한번 변신을 시켜줄 우리의 독수리 로봇이 되겠습니다.

 

 

 

1) 머리(우리의 메인)

 

2) 몸통(합체 되어질)

 

3) 다리(합체 되어질)

 

 

쫘잔~~~+ㅁ+/

 

 

 

아래처럼 합체로봇으로 변신하게 됩니다.

 

 

여기서 다가 아닙니다!! 변신합체 로봇에서 다시 한번 독수리가 합체가 되어서

그 유명한!! 페가서스가 되어집니다!!!! 쫘잔~~~~~~+ㅁ+/

 

변신합체 로봇! 페가서스!!!! 두둥~

자! 데코레이터 패른!!! 시작 해볼까용?~~

개요는 마무리 하고, 먼저 패턴의 클래스 다이어그램을 먼저 살펴 보겠습니다.

 

<< 클래스 다이어그램 >> 

그냥 한번 그려보았다..;;

 

아래와 비교해보면 인터페이스와 추상클래스간의 관계를 그리지 않은 것 같다. 참고하자!

 

<< 예제(Java) >>

1) 결과

   아래의 결과와 같이 변신은 메인 로봇이 머리로! 그 다음엔 바디, 그 다음 다리, 그 다음 뒷다리로 변신이

   되어집니다. ㅋㅋㅋ 전투력은 무려 10만이 넘어가네요+ㅁ+/

Change Center Robot -> Body Combine!!
Change Red Robot -> Combine Leg!!!
Change egle Robot -> Back Leg Combine!!
Main Robot Combine!! to Head, Combine Body!!, Combine Leg!!, Combine Back Leg!!
total power is..103100

 

 

    2) 테스트 코드   

package kr.pe.acet.decorator;

import org.junit.Assert;
import org.junit.Test;

public class DecoratorPatternTest {

 @Test
 public void test() {
  
  Robot mRobot = new BacklegCombine(new LegCombine(new BodyCombine(new  MainRobot())));
  
  Assert.assertNotNull(mRobot);
  
  System.out.println(mRobot.getCombineAction());
  System.out.println("total power is.."+mRobot.getPower());
  
 }

}

 

 

    3) Robot Interface(Decorator pattern에서 중요하게 봐야 할 부분 입니다.)

package kr.pe.acet.decorator;

public interface Robot {
 public String getCombineAction();
 public int getPower();
}
 

 

 

 

    4) MainRobot class

package kr.pe.acet.decorator;

public class MainRobot implements Robot{

 @Override
 public String getCombineAction() {
  // TODO Auto-generated method stub
  return "Main Robot Combine!! to Head";
 }

 @Override
 public int getPower() {
  // TODO Auto-generated method stub
  return 100;
 }
}
 

 

 

    5) CombineDecorator class (Decorator pattern에서 중요하게 봐야 할 부분 입니다.)

package kr.pe.acet.decorator;

public abstract class CombineDecorator implements Robot{
 protected Robot tempRobot;
 
 public CombineDecorator(Robot newRobot){
  tempRobot = newRobot;
 }
 
 public String getCombineAction() {
  // TODO Auto-generated method stub
  return tempRobot.getCombineAction();
 }

 public int getPower() {
  // TODO Auto-generated method stub
  return tempRobot.getPower();
 }
  
}
 

 

 

    6) BodyCombine class

package kr.pe.acet.decorator;

public class BodyCombine extends CombineDecorator{

 public BodyCombine(Robot newRobot) {
  super(newRobot);
  System.out.println("Change Center Robot -> Body Combine!!");
 }

 public String getCombineAction() {
  // TODO Auto-generated method stub
  return tempRobot.getCombineAction()+", Combine Body!!";
 }

 public int getPower() {
  // TODO Auto-generated method stub
  return tempRobot.getPower()+2000;
 }

}
 

 

 

    7) LegCombine class

package kr.pe.acet.decorator;

public class LegCombine extends CombineDecorator{

 public LegCombine(Robot newRobot) {
  super(newRobot);
  System.out.println("Change Red Robot -> Combine Leg!!!");
 }
 
 public String getCombineAction() {
  // TODO Auto-generated method stub
  return tempRobot.getCombineAction()+", Combine Leg!!";
 }

 public int getPower() {
  // TODO Auto-generated method stub
  return tempRobot.getPower()+1000;
 }

}
 

 

 

 8) BacklegCombine class

package kr.pe.acet.decorator;

public class BacklegCombine extends CombineDecorator{

 public BacklegCombine(Robot newRobot) {
  super(newRobot);
  System.out.println("Change egle Robot -> Back Leg Combine!!");
 }

 public String getCombineAction() {
  // TODO Auto-generated method stub
  return tempRobot.getCombineAction()+", Combine Back Leg!!";
 }

 public int getPower() {
  // TODO Auto-generated method stub
  return tempRobot.getPower()+100000;
 }

}
 

 

 

 

<< 같이 보기 >>

http://www.youtube.com/watch?v=j40kRwSm4VE

정말 도움이 많이 된 동영상 입니다. 참고하세요~꼭 보세요~!!

내 책에 있던 소스 코드

 

또 다른 소스 참고! : https://github.com/colorbox/Gof/tree/master/java/Decorator

 

<< 참고 사항 >>

데코레이터 패턴은 객체에 동적으로 새로운 무엇인가를 하고자 할 때 사용 된다. 특히 상속으로 sub Class를 이용하는 것 보다 더 유연성 있게 추가 할 수 있다.

 

 

 

저작자 표시 비영리 변경 금지
신고

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

  • Favicon of http://7network.tistory.com BlogIcon 개굴개굴왕 2014.08.05 14:09 신고 답글 | 수정/삭제 | ADDR

    안녕하세요. 블로그 내용이 좋아서♡ 블로그모음 서비스인 블로그앤미[http://blogand.me] 에 등록했습니다. 원하지 않으시면 삭제하겠습니다. 좋은 하루 되세요. ^^

    • Favicon of http://acet.pe.kr BlogIcon String Ace-T 2014.08.05 17:08 신고 수정/삭제

      ㅎㅎㅎ블로그모음 서비스도 있었군요! 등록해주셔서 감사합니다^^
      그리고 번창하시길 바랍니다~

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

[DesignPattern] memento pattern

Architecture/DesignPattern 2013.12.16 01:31
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T

The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback).

The memento pattern is implemented with three objects: the originator, a caretaker and a memento.

The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object.


출처) 위키피디아

 

memento pattern에는 3가지 객체가 필요하다.

1) originator

    originator

      미국·영국 [ərídƷənèitər] 발음듣기 영국식 발음듣기 다른 뜻(1건) 예문보기

      창작자, 창설자, 창시자, 발기인, 시조

      가. Sets and Gets values from the currently targeted memento object.

      나. Creates new Mementos and assigns current values to them.


2) caretaker

         caretaker

미국식 [|kerteɪkə(r)] / 영국식 [|keəteɪkə(r)]

1. (건물의) 경비원   2. (주택토지의) 관리인   3. 다른 사람을 돌보는 사람

Holds an ArrayList that contains all previous versions of the Memento.

It can store and retrieve stored Mementos.


3) menento

         memento 미국식 [mə|mentoʊ] 발음 듣기 영국식 [mə|mentəʊ] 발음 듣기 
(사람・장소를 기억하기 위한) 기념품 
: 기본 object로 다른 상태들을 저장 한다.


 memento pattern은 이전 상태의 객체를 쉽게 저장하는 방법 중에 하나이다.

 

즉, undo~!! 이전 상태로 돌리는 것이다. 이전 상태로 돌릴려면..어떻게?????

☞ 이전 상태의 오브젝트의 정보를 저장 해야한다.

   오브젝트의 정보를 복원하기 위해서는 자유자재로 해당 오브젝트를 액세스 할 수 있어야 할 것이다.

   하지만 이런식으로 오브젝트를 리플렉션을 하다가는 캡슐화가 보장받지 못하게 된다.

   그래서!! 캡슐화도 보장받고, 저장 및 이전상태로 돌리는(복원) undo를 가능케하는 것이 바로 memento pattern 인 것이다!(멋진데..)

  

 

     

Originator
- Originator는 자신의 현재 상태를 저장하고 싶을 때 Memento를 만든다.(createMemento) 또한, 이전의 Memento object를 전달받으면 그 Memento object를 만든 시점의 상태로 돌리는 처리를 실행한다.

 

package kr.pe.acet.memento;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
 
public class Gamer {
    private int money;
    private List<String> fruits = new ArrayList<String>();
    private Random random = new Random();
    private static String[] fruitsname = {
        "사과", "포도", "바나나", "귤"
    };
     
    public Gamer(int money){
        this.money = money;
    }
    
    public int getMoney(){
        return money;
    }
    
    public void bet(){
        int dice = random.nextInt(6) + 1;
        if(dice == 1){
            money += 100;
            System.out.println("소지금이 증가했습니다.");
        }else if(dice == 2){
            money /= 2;
            System.out.println("소지금이 절반이 되었습니다.");
        }else if(dice == 6){
            String f = getFruit();
            System.out.println("과일(" + f + ")을 받았습니다.");
            fruits.add(f);
        }else{
            System.out.println("변한 것이 없습니다.");
        }
    }
    
    public Memento createMemento(){
        Memento m = new Memento(money);
        Iterator it = fruits.iterator();
        
        while(it.hasNext()){
            String f = (String)it.next();
            if(f.startsWith("맛있는")){
                m.addFruit(f);
            }
        }
        
        return m;
    }
    
    public void restoreMemento(Memento memento){
        this.money = memento.money;
        this.fruits = memento.getFruits();
    }
    
    public String toString(){
        return "[money = " + money + ", fruits = " + fruits + "]";
    }
    
    private String getFruit(){
        String prefix = "";
        if(random.nextBoolean()){
            prefix = "맛있는 ";
        }
        
        return prefix + fruitsname[random.nextInt(fruitsname.length)];
    }
}

 

 

Memento의 역할
- Memento 역할은 Originator 역할의 내부 정보를 정리한다. Memento 역할은 Originator 역할의 내부 정보를 가지고 있지만, 그 정보를 누구에게도 공개하지 않는다. Memento 역할은 다음 두 종류의 인터페이스를 가지고 있다.

1. wide interface : Memento class에서 제공하는 이 인터페이스는 오브젝트의 상태를 원래의 상태로 돌리기 위해 필요한 정보를 모두 얻을 수 있는 메소드의 집합이다. 이 인터페이스는 Memento 역할의 내부상태를 속속들이 들어내기 때문에 이것을 사용하는 것은 Originator class 뿐이다.
2. narrow interface : Memento 역할이 제공하는 이 인터페이스는 외부의 Caretaker class에게 보여주는 것이다.

   이 인터페이스로 할 수 있는 일에는 한계가 있고 내부 상태가 외부에 공개되는 것을 방지한다.

이 두 종류의 인터페이스를 구별해서 사용하면 오브젝트의 캡슐화를 보장 받을 수 있다.

 

package kr.pe.acet.memento;

import java.util.ArrayList;
import java.util.List;
 
public class Memento {
    int money;
    ArrayList<String> fruits;
     
     public int getMoney(){    //narrow interface(외부의 Caretaker class에게 보여주는 것)
         return money;
     }
     
     Memento(int money){    //wide interface(오브젝트의 상태를 원래의 상태로 돌리기 위해..Originator class에서 접근)
         this.money = money;
         this.fruits = new ArrayList<String>();
     }
     
     void addFruit(String fruit){    //wide interface
         fruits.add(fruit);
     }
     
     @SuppressWarnings("unchecked")
     List<String> getFruits(){    //wide interface
         return (List<String>)fruits.clone();
     }
}

 

 

 Caretaker의 역할
- Caretaker 역할은 현재의 Originator 역할의 상태를 저장하고 싶을 때, 그것을 Originator 역할에게 전한다. Originator 역할은 그것을 받아서 Memento 역할을 만들어 Caretaker 역할에게 전달한다. Caretaker 역할은 미래의 필요에 대비해서 그 Memento 역할을 저장해 둔다.
Caretaker 역할은 Memento 역할이 갖는 2종류의 인터페이스중에서 narrow interface만 사용할 수 있으므로 Memento 역할의 내부 정보에 액세스할 수 없다. 

 

package kr.pe.acet.memento;

import static org.junit.Assert.*;

import org.junit.Test;

public class Caretaker {

 @Test
 public void careTakerTest() {
      Gamer gamer = new Gamer(100);                     // originator
      Memento memento = gamer.createMemento(); 
          
      for(int i = 0; i < 10; i++){
            System.out.println("==== " + i);
            System.out.println("현상 : " + gamer);  //  return "[money = " + money + ", fruits = " + fruits + "]"; 
              
            gamer.bet();
              
            System.out.println("소지금은 " + gamer.getMoney() + "원이 되었습니다.");
             
            if(gamer.getMoney() > memento.getMoney()){
                System.out.println(" (많이 증가했으므로 현재의 상태를 저장하자)");
                memento = gamer.createMemento();
            }else if(gamer.getMoney() < memento.getMoney() / 2){
                System.out.println(" (많이 감소했으므로 이전의 상태로 복원하자)");
                gamer.restoreMemento(memento);
            }
             
            try{
                Thread.sleep(1000);
             }catch(InterruptedException e){
                 e.printStackTrace();
             }
              
             System.out.println("");
        }
 
 
 }

}

 

 

 

결과

==== 0
현상 : [money = 100, fruits = []]
과일(맛있는 포도)을 받았습니다.
소지금은 100원이 되었습니다.

==== 1
현상 : [money = 100, fruits = [맛있는 포도]]
변한 것이 없습니다.
소지금은 100원이 되었습니다.

==== 2
현상 : [money = 100, fruits = [맛있는 포도]]
소지금이 증가했습니다.
소지금은 200원이 되었습니다.
 (많이 증가했으므로 현재의 상태를 저장하자)

==== 3
현상 : [money = 200, fruits = [맛있는 포도]]
변한 것이 없습니다.
소지금은 200원이 되었습니다.

==== 4
현상 : [money = 200, fruits = [맛있는 포도]]
과일(귤)을 받았습니다.
소지금은 200원이 되었습니다.

==== 5
현상 : [money = 200, fruits = [맛있는 포도, 귤]]
변한 것이 없습니다.
소지금은 200원이 되었습니다.

==== 6
현상 : [money = 200, fruits = [맛있는 포도, 귤]]
변한 것이 없습니다.
소지금은 200원이 되었습니다.

==== 7
현상 : [money = 200, fruits = [맛있는 포도, 귤]]
변한 것이 없습니다.
소지금은 200원이 되었습니다.

==== 8
현상 : [money = 200, fruits = [맛있는 포도, 귤]]
변한 것이 없습니다.
소지금은 200원이 되었습니다.

==== 9
현상 : [money = 200, fruits = [맛있는 포도, 귤]]
변한 것이 없습니다.
소지금은 200원이 되었습니다. 

 Tip. 스택, 큐 등을 이용하여 히스토리로써 관리할 수도 있다. 또한 serialization을 통해서 파일로 관리하도록 기능을 확장할 수 있다. 

 

마지막으로 요 동영상은 꼭보자!

http://www.youtube.com/watch?v=jOnxYT8Iaoo


참고 사이트 : http://scotty83.tistory.com/entry/Memento-Pattern

 

      참고 사항

2013/11/24 - [Architecture/DesignPattern] - [DesignPattern] observer pattern

 

2013/11/24 - [Architecture/DesignPattern] - [DesignPattern] Interpreter pattern

 

2013/07/21 - [Architecture/DesignPattern] - [첫번째 스터디] singleton 패턴

 

2013/12/03 - [Architecture/DesignPattern] - [DesignPattern] command pattern

 

2013/12/09 - [Architecture/DesignPattern] - [DesignPattern] mediator pattern

 

2013/07/21 - [Architecture/DesignPattern] - [첫번째 스터디] abstractFactory 패턴

 

저작자 표시 비영리 변경 금지
신고

'Architecture > DesignPattern' 카테고리의 다른 글

[DesignPattern] flyweight pattern  (0) 2014.01.06
[DesignPattern] state pattern  (0) 2013.12.31
[DesignPattern] memento pattern  (0) 2013.12.16
[DesignPattern] mediator pattern  (0) 2013.12.09
[DesignPattern] command pattern  (0) 2013.12.03
[DesignPattern] observer pattern  (0) 2013.11.24

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

[DesignPattern] Interpreter pattern

Architecture/DesignPattern 2013.11.24 22:41
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T

 

2013/07/21 - [Architecture/DesignPattern] - [첫번째 스터디] singleton 패턴

 

2013/07/21 - [Architecture/DesignPattern] - [첫번째 스터디] abstractFactory 패턴

지금까지 공부 한 디자인 패턴 목록

  : http://acet.pe.kr/notice/325

 

음..정리는 2개뿐이 하질 않았군요.. 하하;;

 

프로젝트와 병행을 하고 있어서..11월 19일부터 내부 스터디 다시 시작 합니다^-^/

 

매주 월요일 - 눈이 오나 비가오나 지구가 망해도 스터디는 진행 합니다. 아무도 참여하지 않아도 진도는 나갑니다.ㅋㅋㅋㅋ

 

<< 2013년 11월 19일 >>

범 위  : Interperter 패턴

참여 인원 : 4명 중 3명 참여

  참 여 : 공K, 박D, Mr. 권

  불 참 : 이D(교육 참여)

 

참고 사이트 : http://ko.wikipedia.org/wiki/%EC%98%B5%EC%84%9C%EB%B2%84_%ED%8C%A8%ED%84%B4

 

인터프리터 패턴 이란??

In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language.

위의 빨간 문장이 어떻게 보면 핵심인 것 같다. 영어라서 그런지..해석해보면 Interpreter가 뭔지 잘 모르면

난감 할 수 있는 문장이다.

evaluate를 네이버에서 찾아보면 아래와 같다 ㅋㅋ

더보기

 

 암튼 해석을 해보면 어떤 특별한(상징적인) 문장을 평가(해석)한다는 뜻이다.

 

The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence

 

syntax tree 라는 것은 예를 들어서 a b + c a - -  이런 상징적인 녀석들이 모여서 차례차례 수행이 되는데

      syntax tree라는 용어를 사용 한다. 소스에서 syntax tree라는 변수가 있으니 그 용도를 보면 알 것 이다.

구조를 살펴보도록 하자! 

 

 

 

소스 -  패키지는 package kr.pe.acet.interpreter; 이다.

 

InterpreterPatternTest.java

 

Evaluator.java

 

Expression.java

 

Minus.java

 

Number.java

 

Plus.java

 

Variable.java

 

저작자 표시 비영리 변경 금지
신고

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

[첫번째 스터디] abstractFactory 패턴

Architecture/DesignPattern 2013.07.21 00:42
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T

part 2. abstractFactory pattern


추상 팩토리 패턴..!!


팩토리 패턴은 매우 다양한 것 같다..뒤에도 나오겠지만 Factory Method 라는 녀석도 있다. @.@;;

Factory 패턴은 생성 패턴이라고도 부른다.

즉, 객체를 생성해주는 패턴이라고 보면 된다. 

아래의 소스에서 보면 KRAddress와 USAddress.java가 생성이 되어야하는 대상 이다.

어떻게 생성을 해주어야 하는가는 소스를 보면 파악 할 수 있을 것이다.

하지만 헷깔릴수 있는 소지가 다분하다. 바로 팩토리 이녀석도 추상적인 개념을 넣어서 interface구조 또는 abstract구조로 나뉘어져있기 때문이다.




위의 소스의 구성을 보면 복잡하게 느낄 수도 있겠지만 사실은 간단하다.

 

 

AddressFactory.java


Client.java


KRAddress.java


KRAddressFactory.java


USAddress.java


USAddressFactory.java


abstractFactoryTest.java




소스를 보기 전에 간단히 설명을 하면



인터페이스와 이를 구현하는 구조로 되어있다. 즉, 만들어야 할 객체와 팩토리가 인터페이스+구현부 자바로 되어있다는 것이다.
 

 

package kr.pe.acet.abstractFactory;

public interface Address {

public String getFullAddress();

}

위의 Address 를 구현한 것이 아래의 KRAddress.java 인 것이다.
package kr.pe.acet.abstractFactory;

public class KRAddress implements Address{

	@Override
	public String getFullAddress() {
		// TODO Auto-generated method stub
		return "서울시 은평구 신사1동";
	}
}
팩토리를 추상화 시켜 놓은 것이다.
package kr.pe.acet.abstractFactory;

public interface AddressFactory {

	public Address createAddress();
	
	
}
위의 AddressFactory.java를 구현 한 것이 아래의 KRAddressFactory.java 이다.
package kr.pe.acet.abstractFactory;

public class KRAddressFactory implements AddressFactory{

	KRAddressFactory krAddressFactory = null;
	@Override
	public Address createAddress() {
		return new KRAddress();
	}
	

}

특히, 내가 추상 팩토리 패턴을 구현 하면서 제일 어려웠던 것은 Client.java이다. 어떤식으로 연결을 해주어야 할지 막막 하였다..
package kr.pe.acet.abstractFactory;

public class Client {

	AddressFactory addressFactory = null;
	
	
	public Address createAddress(String countryType) {
		// TODO Auto-generated method stub
		AddressFactory addressFactory = getAddressFactory(countryType);
		return addressFactory.createAddress();
	}

	private AddressFactory getAddressFactory(String countryType) {
		// TODO Auto-generated method stub
		if("KR".equals(countryType)){
			return new KRAddressFactory();
		}else if("US".equals(countryType)){
			return new USAddressFactory();
		}
		return null;
	}
	
	

}

TEST쪽에서 client 객체를 생성하여 아래처럼 접근하면..끝이다! 
팩토리와 객체 모두 생성이 되어진다. 내부적으로 알아서~~ 
Address addressKr = client.createAddress("KR"); 
그리고 Address를 구현한 객체를 생성 한 뒤 리턴을 해주고 그 생성한 객체의 메소드를 접근 할 수 있게 된다. System.out.println("abstract Factory output=>"+addressKr.getFullAddress());


 Part2. 추상팩토리 끝~



2013/07/21 - [Architecture/DesignPattern] - [첫번째 스터디] singleton 패턴


저작자 표시 비영리 변경 금지
신고

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

[첫번째 스터디] singleton 패턴

Architecture/DesignPattern 2013.07.21 00:09
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T


2013년 07월10 사내 스터디가 부활 하였다. 두둥~

2번째 용수철 스터디가 시작 되었다.

처음에는 굿택과 둘이서 하려고 하였다가 2명을 더 추가하여 소스정예로 하게 되었다.^-^good~


이번 사내 스터디의 내용은 디자인 패턴이다!!!

개발코드를 중심으로 하는 스터디 이며, 매우 성실하게!! 해야 할 것이다.


이제 주저리는 그만하고..본론으로 패턴에 대해 알아보도록 하겠다^-^



part 1. singleton pattern


싱글톤 패턴!!~


싱글+톤


마치..싱글 : 혼자, 하나 인 느낌

톤 : 스켈레톤 할 때 뼈대의 느낌 인 듯 하다.


그래서 싱글톤은 하나의 뼈대?? 라고 생각하면 될 것 같다.(저만의 생각입져..ㄷㄷ)

즉, java에서는 oop 즉 객제지향으로 봤을 때 싱글톤의 하나의 뼈대란 하나의 객체로 볼 수 있다.


매번 객체를 생성하는 것이 아니라 하나 만들어놓고 쭉~~~~쓴다는 것이다.

보통 데이터베이스를 접근 할 때 매번 접근 하는 것이 아니라 하나의 dao(data access object)를 만들어두고 

접근을 계속하게 되면 매번 connection을 하지 않아도 된다. 즉, 그만큼 비용이 절감 될 것이다.


이론은 이제 그만~~~몸소 체험을 해보자!! 코드로 말하자!!

디자인 패턴! 잡으로 가보자잉~~ 



소스의 패키지는 아래와 같다.



Junit으로 동작을 한다.



JUNIT 테스트 코드

package kr.pe.acet.singleton;

import static org.junit.Assert.*;
import kr.pe.acet.singleton.SingletonPattern;
import org.junit.Test;

public class SingletonPatternTest {

	@Test
	public void singleTonTest() {
		
		// set variable
		SingletonPattern mySingleton = null, yourSingleton=null;
		
		// get the object
		mySingleton = SingletonPattern.getInstance();
		yourSingleton = SingletonPattern.getInstance();
		
		// confirm the object
		assertEquals(mySingleton.print("Junit Test!!"), "Junit Test!!");
		assertEquals(yourSingleton.print("SingleTone Test!!"), "SingleTone Test!!");
		assertEquals("OK!!",yourSingleton, mySingleton);
	}

}


assertEquals("OK!!",yourSingleton, mySingleton); 마지막 라인처럼 객체가 서로 같은지 비교 한다.

package kr.pe.acet.singleton;

/**
 * @author acet
 *
 */
public class SingletonPattern {

	private static SingletonPattern singleton;
	
	private SingletonPattern(){
		
	}
	
	public static SingletonPattern getInstance(){
		if(singleton == null){
			synchronized(SingletonPattern.class){
				if(singleton == null)
				singleton = new SingletonPattern();
			}
			
		}
		return singleton;
	}
	
	public String print(String str){
		System.out.println("출력 : "+str);
		return str;
	}
	
	// private volatile static ~~
	// 쓰레드는 
	
	
}

결과

출력 : Junit Test!! 

출력 : SingleTone Test!!





스터디를 하면서 싱글톤의 종류? 사용 방법이 3개쯤 소개가 되었다. 
그중에 가장 많이 쓰이는 것이 위의 방법이다. 
synchronized를 언제 해주는가 하는 시점 차이와 singleton == null 을 체크를 언제 해주냐 하는 시점의 차이가 있다. 
 맨 밑의 라인에 뵈는 volatile 은 또한 중요한 개념이였다. 
간단히 말하면 쓰레드들은 메모리를 복사해서 쓰는데 있어서 위의 volatile 키워드를 사용하면 복사를 하지 않고 메모리에 올라와있는 원본을 가지고 사용하게 된다. 
즉, 혹시나 모르는 변경에 대한 리스크를 막을 수가 있다. 
자세한 내용은 구글링을 해보면 좋을 것이다^-^good~

 part 1. singleton pattern END 

 To be Continue..



2013/07/21 - [Architecture/DesignPattern] - [첫번째 스터디] abstractFactory 패턴


저작자 표시 비영리 변경 금지
신고

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

티스토리 툴바