File:State Design Pattern UML Class Diagram.svg

http://en.wikipedia.org/wiki/State_pattern


스테이트 패턴을 이용하면 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있다. 마치 객체 클래스가 바뀌는 것과 같은 결과를 얻을 수 있다.


Strategy pattern과의 차이점


state pattern은 상태 객체의 일련의 행동이 캡슐화 됨

strategy pattern은 일반적으로 클라이언트에서 컨택스트 객체한테 어떤 전략 객체를 사용할지를 지정해 중



interface Statelike {
 
    void writeName(StateContext context, String name);
 
}
 
class StateLowerCase implements Statelike {
 
    @Override
    public void writeName(final StateContext context, final String name) {
        System.out.println(name.toLowerCase());
        context.setState(new StateMultipleUpperCase());
    }
 
}
 
class StateMultipleUpperCase implements Statelike {
    /** Counter local to this state */
    private int count = 0;
 
    @Override
    public void writeName(final StateContext context, final String name) {
        System.out.println(name.toUpperCase());
        /* Change state after StateMultipleUpperCase's writeName() gets invoked twice */
        if(++count > 1) {
            context.setState(new StateLowerCase());
        }
    }
 
}

http://en.wikipedia.org/wiki/Composite_pattern


컴포지트패턴을 이용하면 객체들을 트리구조로 구성하여 부분과 전체를 나타내는 계층구조로 만들 수 있다. 이 패턴을 이용하면 클라이언트에서 계별 객체와 다른 객체들로 구성된 복합객체를 똑같은 방법으로 다룰 수 있다.



import java.util.List;
import java.util.ArrayList;
 
/** "Component" */
interface Graphic {
 
    //Prints the graphic.
    public void print();
 
}
 
/** "Composite" */
class CompositeGraphic implements Graphic {
 
    //Collection of child graphics.
    private List mChildGraphics = new ArrayList();
 
    //Prints the graphic.
    public void print() {
        for (Graphic graphic : mChildGraphics) {
            graphic.print();
        }
    }
 
    //Adds the graphic to the composition.
    public void add(Graphic graphic) {
        mChildGraphics.add(graphic);
    }
 
    //Removes the graphic from the composition.
    public void remove(Graphic graphic) {
        mChildGraphics.remove(graphic);
    }
 
}
 
 
/** "Leaf" */
class Ellipse implements Graphic {
 
    //Prints the graphic.
    public void print() {
        System.out.println("Ellipse");
    }
 
}
 
 
/** Client */
public class Program {
 
    public static void main(String[] args) {
        //Initialize four ellipses
        Ellipse ellipse1 = new Ellipse();
        Ellipse ellipse2 = new Ellipse();
        Ellipse ellipse3 = new Ellipse();
        Ellipse ellipse4 = new Ellipse();
 
        //Initialize three composite graphics
        CompositeGraphic graphic = new CompositeGraphic();
        CompositeGraphic graphic1 = new CompositeGraphic();
        CompositeGraphic graphic2 = new CompositeGraphic();
 
        //Composes the graphics
        graphic1.add(ellipse1);
        graphic1.add(ellipse2);
        graphic1.add(ellipse3);
 
        graphic2.add(ellipse4);
 
        graphic.add(graphic1);
        graphic.add(graphic2);
 
        //Prints the complete graphic (four times the string "Ellipse").
        graphic.print();
    }
}

Iterator UML class diagram.svg

http://jmnote.com/wiki/Iterator_%ED%8C%A8%ED%84%B4


이터레이터 패턴은 컬랙션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어가있는 모든 항목에 접근할 수 있게 해주는 방법을 제공해줍니다.


클래스를 바꾸는 이유는 한가지 뿐이어야 한다.


File:Template Method UML.svg

http://en.wikipedia.org/wiki/Template_metho


템플릿 메소드 패턴에서는 매소드에서 알고리즘의 골격을 정의한다. 알고리즘의 여러단계 중 일부는 서브클래서에서 구현할 수 있다. 템플릿 메소드를 이용하면 알고리즘의 구조는 그대로 유지하면서 서브클래서에서 특정 단계를 지정할수도 있다.


헐리우드 원칙



/**
 * An abstract class that is common to several games in
 * which players play against the others, but only one is
 * playing at a given time.
 */
 
abstract class Game {
 
    protected int playersCount;
    abstract void initializeGame();
    abstract void makePlay(int player);
    abstract boolean endOfGame();
    abstract void printWinner();
 
    /* A template method : */
    public final void playOneGame(int playersCount) {
        this.playersCount = playersCount;
        initializeGame();
        int j = 0;
        while (!endOfGame()) {
            makePlay(j);
            j = (j + 1) % playersCount;
        }
        printWinner();
    }
}
 
//Now we can extend this class in order 
//to implement actual games:
 
class Monopoly extends Game {
 
    /* Implementation of necessary concrete methods */
    void initializeGame() {
        // Initialize players
        // Initialize money
    }
    void makePlay(int player) {
        // Process one turn of player
    }
    boolean endOfGame() {
        // Return true if game is over 
        // according to Monopoly rules
    }
    void printWinner() {
        // Display who won
    }
    /* Specific declarations for the Monopoly game. */
 
    // ...
}
 
class Chess extends Game {
 
    /* Implementation of necessary concrete methods */
    void initializeGame() {
        // Initialize players
        // Put the pieces on the board
    }
    void makePlay(int player) {
        // Process a turn for the player
    }
    boolean endOfGame() {
        // Return true if in Checkmate or 
        // Stalemate has been reached
    }
    void printWinner() {
        // Display the winning player
    }
    /* Specific declarations for the chess game. */
 
    // ...
}

high cohesion, low coupling


cohesion: 한 모듈이 얼마나 관련된 일로만 구성되어 있는가?

coupling: 두개이상의 object가 얼마나 관계되어 있는가?


설계할 때 아주 중요하다.

File:Example of Facade design pattern in UML.png

http://en.wikipedia.org/wiki/Facade_pattern


어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공한다. 퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용할 수 있다.


최소 지식원칙, 정말로 친한 친구끼리만 얘기해라.


/* Complex parts */
 
class CPU {
	public void freeze() { ... }
	public void jump(long position) { ... }
	public void execute() { ... }
}
 
class Memory {
	public void load(long position, byte[] data) {
		...
	}
}
 
class HardDrive {
	public byte[] read(long lba, int size) {
		...
	}
}
 
/* Façade */
 
class Computer {
	public void startComputer() {
		cpu.freeze();
		memory.load(BOOT_ADDRESS, hardDrive.read(BOOT_SECTOR, SECTOR_SIZE));
		cpu.jump(BOOT_ADDRESS);
		cpu.execute();
	}
}
 
/* Client */
 
class You {
	public static void main(String[] args) throws ParseException {
		Computer facade = /* grab a facade instance */;
		facade.startComputer();
	}
}

http://en.wikipedia.org/wiki/Adapter_pattern

Object Adapter


http://en.wikipedia.org/wiki/Adapter_pattern

Class Adapter


한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른인터페이스로 변환한다. 어댑터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 쓸 수 있다.

# Python code sample
class Target(object):
    def specific_request(self):
        return 'Hello Adapter Pattern!'
 
class Adapter(object):
    def __init__(self, adaptee):
        self.adaptee = adaptee
 
    def request(self):
        return self.adaptee.specific_request()
 
client = Adapter(Target())
print client.request()

Command Design Pattern Class Diagram.png

http://ko.wikipedia.org/wiki/%EC%BB%A4%EB%A7%A8%EB%93%9C_%ED%8C%A8%ED%84%B4


커맨드 패턴을 이용하면 요구사항을 객체로 캡슐화 할 수 있다. 매개변수를 써서 여러가지 요구사항을 만들 수도 있다. 또한 요청내역을 큐에 저장하여 로그를 기록하는 것도 가능하고 작업 취소 구현도 가능하다.

/*the Invoker class*/
public class Switch {
    private Command flipUpCommand;
    private Command flipDownCommand;
 
    public Switch(Command flipUpCmd,Command flipDownCmd){
            this.flipUpCommand=flipUpCmd;
            this.flipDownCommand=flipDownCmd;
           }
 
    public void flipUp(){
         flipUpCommand.execute();
    }
 
    public void flipDown(){
         flipDownCommand.execute();
    }
}
 
/*Receiver class*/
 
public class Light{
     public Light(){  }
 
     public void turnOn(){
        System.out.println("The light is on");
     }
 
     public void turnOff(){
        System.out.println("The light is off");
     }
}
 
 
/*the Command interface*/
 
public interface Command{
    void execute();
}
 
 
/*the Command for turning on the light*/
 
public class TurnOnLightCommand implements Command{
   private Light theLight;
 
   public TurnOnLightCommand(Light light){
        this.theLight=light;
       }
 
   public void execute(){
      theLight.turnOn();
   }
}
 
/*the Command for turning off the light*/
 
public class TurnOffLightCommand implements Command{
   private Light theLight;
 
   public TurnOffLightCommand(Light light){
        this.theLight=light;
       }
 
   public void execute(){
      theLight.turnOff();
   }
}
 
/*The test class*/
public class TestCommand{
   public static void main(String[] args){
       Light light=new Light();
       Command switchUp=new TurnOnLightCommand(light);
       Command switchDown=new TurnOffLightCommand(light);
 
       Switch s=new Switch(switchUp,switchDown);
 
       s.flipUp();
       s.flipDown();
   }
}

Singleton.png

http://en.wikipedia.org/wiki/Singleton_pattern


객체를 하나만 만들때 사용


참고, 자바에서 volatile 키워드를 사용하면 멀티스레딩을 쓰더라도 uniqueInstance 변수와 singleton인스턴스로 초기화 되는 과정이 올바르게 진행되도록 할 수 있다.

File:Abstract factory UML.svg

http://en.wikipedia.org/wiki/Abstract_factory

+ Recent posts