2015년 11월 6일 금요일

클래스 디자인 패턴 23. Interpreter Pattern

1. 개념
  1) 의미
     목적상 변경이 이루어질때 기존 코드를 수정하지 않고
       통역 역할을 하는 프로그램을 만들어 실행하는 패턴입니다.


2. 소스

  1) Node 추상 클래스 작성

public abstract class Node {
    public abstract void parse(Context context) throws ParseException;
}
     

     이를 상속하여 각 문법 하나하나에 대응하는
       객체들을 생성한다.

// <program> ::= program <command list>
public class ProgramNode extends Node {
    private Node commandListNode;
    public void parse(Context context) throws ParseException {
        context.skipToken("program");
        commandListNode = new CommandListNode();
        commandListNode.parse(context);
    }
    public String toString() {
        return "[program " + commandListNode + "]";
    }
}


import java.util.Vector;

// <command list> ::= <command>* end
public class CommandListNode extends Node {
    private Vector list = new Vector();
    public void parse(Context context) throws ParseException {
        while (true) {
            if (context.currentToken() == null) {
                throw new ParseException("Missing 'end'");
            } else if (context.currentToken().equals("end")) {
                context.skipToken("end");
                break;
            } else {
                Node commandNode = new CommandNode();
                commandNode.parse(context);
                list.add(commandNode);
            }
        }
    }
    public String toString() {
        return "" + list;
    }
}


// <command> ::= <repeat command> | <primitive command>
public class CommandNode extends Node {
    private Node node;
    public void parse(Context context) throws ParseException {
        if (context.currentToken().equals("repeat")) {
            node = new RepeatCommandNode();
            node.parse(context);
        } else {
            node = new PrimitiveCommandNode();
            node.parse(context);
        }
    }
    public String toString() {
        return node.toString();
    }
}


// <repeat command> ::= repeat <number> <command list>
public class RepeatCommandNode extends Node {
    private int number;
    private Node commandListNode;
    public void parse(Context context) throws ParseException {
        context.skipToken("repeat");
        number = context.currentNumber();
        context.nextToken();
        commandListNode = new CommandListNode();
        commandListNode.parse(context);
    }
    public String toString() {
        return "[repeat " + number + " " + commandListNode + "]";
    }
}


// <primitive command> ::= go | right | left
public class PrimitiveCommandNode extends Node {
    private String name;
    public void parse(Context context) throws ParseException {
        name = context.currentToken();
        context.skipToken(name);
        if (!name.equals("go") && !name.equals("right") && !name.equals("left")) {
            throw new ParseException(name + " is undefined");
        }
    }
    public String toString() {
        return name;
    }
}


  2) 구문 해석에 필요한 Context 클래스를 작성합니다.
      그 하단은 exception 처리 클래스 입니다.

import java.util.*;

public class Context {
    private StringTokenizer tokenizer;
    private String currentToken;
    public Context(String text) {
        tokenizer = new StringTokenizer(text);
        nextToken();
    }
    public String nextToken() {
        if (tokenizer.hasMoreTokens()) {
            currentToken = tokenizer.nextToken();
        } else {
            currentToken = null;
        }
        return currentToken;
    }
    public String currentToken() {
        return currentToken;
    }
    public void skipToken(String token) throws ParseException {
        if (!token.equals(currentToken)) {
            throw new ParseException("Warning: " + token + " is expected, but " + currentToken + " is found.");
        }
        nextToken();
    }
    public int currentNumber() throws ParseException {
        int number = 0;
        try {
            number = Integer.parseInt(currentToken);
        } catch (NumberFormatException e) {
            throw new ParseException("Warning: " + e);
        }
        return number;
    }
}


public class ParseException extends Exception {
    public ParseException(String msg) {
        super(msg);
    }
}


  3) 테스트 코드 입니다.

import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader("program.txt"));
            String text;
            while ((text = reader.readLine()) != null) {
                System.out.println("text = \"" + text + "\"");
                Node node = new ProgramNode();
                node.parse(new Context(text));
                System.out.println("node = " + node);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


결과 : text는 실제 내용 node는 해석 결과
node = [program []]
text = "program go end"
node = [program [go]]
text = "program go right go right go right go right end"
node = [program [go, right, go, right, go, right, go, right]]
text = "program repeat 4 go right end end"
node = [program [[repeat 4 [go, right]]]]
text = "program repeat 4 repeat 3 go right go left end right end end"
node = [program [[repeat 4 [[repeat 3 [go, right, go, left]], right]]]]

3. 다이어그램
http://zetawiki.com/wiki/Interpreter_%ED%8C%A8%ED%84%B4


4. 관련패턴
  1)

클래스 디자인 패턴 22. Flyweight Pattern

1. 개념
  1) 의미
     객체를 가볍게 하기 위한 패턴 메모리를
        좀더 적게 사용하여 객체를 표현하는 방법을 다룹니다.


2. 소스

  1)  txt 파일로 0~9까지 큰 숫자를 작성합니다.



  2) 숫자를 char로 받아서 해당 txt 파일을 확인하는 BigChar  클래스를
     작성합니다.

package a;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BigChar {
    // 문자의 이름
    private char charname;
    // 큰 문자를 표현하는 문자열('#' '.' '\n'의 열)
    private String fontdata;
    // 생성자
    public BigChar(char charname) {
        this.charname = charname;
        try {
        //System.out.println("big"+charname +".txt");
            BufferedReader reader = new BufferedReader(
                new FileReader("big" + charname + ".txt")
            );
            String line;
            StringBuffer buf = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                buf.append(line);
                buf.append("\n");
            }
            reader.close();
            this.fontdata = buf.toString();
        } catch (IOException e) {
            this.fontdata = charname + "?";
        }
    }
    // 큰 문자를 표시한다.
    public void print() {
        System.out.print(fontdata);
    }
}




  3) BigCharFactory 클래스를 작성합니다. 이 클래스는
      bigchar 클래스의 인스턴스를 공유, 및 생성합니다.

package a;
import java.util.Hashtable;

public class BigCharFactory {
    // 이미 만들어진 BigChar의 인스턴스를 관리
    private Hashtable pool = new Hashtable();
    // Singleton 패턴
    private static BigCharFactory singleton = new BigCharFactory();
    // 생성자
    private BigCharFactory() {
    }
    // 유일한 하나의 인스턴스를 얻는다.
    public static BigCharFactory getInstance() {
        return singleton;
    }
    // BigChar의 인스턴스 생성(공유)
    public synchronized BigChar getBigChar(char charname) {
        BigChar bc = (BigChar)pool.get("" + charname);
        if (bc == null) {
            bc = new BigChar(charname); // 여기에서 BigChar의 인스턴스를 생성
            pool.put("" + charname, bc);
        }
        return bc;
    }
}


  4) BigString 클래스에서는 큰 숫자 인스턴스를 이용해
      화면에 뿌려줍니다.

package a;
public class BigString {
    // "큰 문자"의 배열
    private BigChar[] bigchars;
    // 생성자
    public BigString(String string) {
        bigchars = new BigChar[string.length()];
        BigCharFactory factory = BigCharFactory.getInstance();
        for (int i = 0; i < bigchars.length; i++) {
            bigchars[i] = factory.getBigChar(string.charAt(i));
        }
    }
    // 표시
    public void print() {
        for (int i = 0; i < bigchars.length; i++) {
            bigchars[i].print();
        }
    }
}


  5) 테스트 를 위한 클래스입니다.
      argument 에 숫자를 넣으면 결과에 큰숫자를 보여주게끔
     작성합니다.

package a;
public class Main {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage: java Main digits");
            System.out.println("Example: java Main 1212123");
            System.exit(0);
        }

        BigString bs = new BigString(args[0]);
        bs.print();
    }
}



결과 : (블로그라 좀 찌그러져 보입니다.
....######....
....##......##....
...............##....
.........####.....
...............##.....
....##......##....
....######....
.........................

3. 다이어그램
https://ko.wikipedia.org/wiki/%ED%94%8C%EB%9D%BC%EC%9D%B4%EC%9B%A8%EC%9D%B4%ED%8A%B8_%ED%8C%A8%ED%84%B4


4. 관련패턴
  1) Proxy 패턴
       인스턴스 생성에 시간이 거리는 경우 인스턴스를 공유하여
        처리 속도를 향상시킬 수 있습니다.
       Proxy 에서는 대리인을 내세워 처리 속도를 올립니다.

  2) Composite 패턴
       Composite의 Leaf 역활을 담당할 수 있습니다.

  3) Singleton 패턴
       Singleton 패턴이 Factory 역할을 겸할 수 있습니다.
       하나의 인스턴스를 가지는 Singleton이 여러곳에서
       공유되는 점이 비슷합니다.

2015년 11월 3일 화요일

협업도구?팀프로젝트관리?3.캔버스

1. 캔버스
  1) 의미
     캔버스는 그림을 그릴때 쓰는 종이다. 
     https://ko.wikipedia.org/wiki/%EC%BA%94%EB%B2%84%EC%8A%A4
    
     요즘 협업도구 라는 용어에 관심이 가서 이전부터 쓰이는거 말고
      (Office Access 나 jira, redmind 정도) 좀더 간단하고
      굳이 it 가 아니더라도 학습 시간을 적게 사용하여 
      활용할 수 있는게 있을가 싶어서 찾던중 발견하게 된 아이템

  2) 특징
    (1) 이건 이전에 소개한 트렐로나 콜라비와는 다른 영역임
           화이트보드를 큰거 하나주고 도구를 이용해 그리거나
           하여 이 큰 판을 구성원들과 공유하고 
           수정하는 정도의 기능

    (2) 물론 일을 받거나 주거나 하지도 않고 할당도 하지 않는다.

    (3) 타임라인이 있고 (작업시 팀원들에게 알림이 감)
          공동 공간에 작성된 하나의 화면을 팀원과 공유함
          + 팀원간 카톡처럼 채팅 기능이 있음.

    (4) 작성이 간단하고 어느 사무실에나 화이트 보드는 많으면
          많을수록 좋고 뭔가 구조도를 여기저기 그려놓으면
          아직 구현하지 않았지만 마음이 차분해지므로 
          좋은 툴이라고 생각함


  3) 이용방법
      여기도 아래 링크로 가서 가입 후 프로젝트를 만들면 
       프로젝트 밑에 캔버스가 하나 생기며 프로젝트를 클릭시
       하얀 판과 좌측에 메뉴를 부여해준다. 이걸로 그리면 됨
      사용한도는 생상한 캔버스 + 첨부파일 용량에 따르며 무료
       정책으로는 300M까지 사용 가능하다.

2. 사용해보기(이용하는 방법)


   처음 들어오면 위와 같은 상황 화면이 뜨는데
    각 프로젝트 안에 하나 이상의 화이트 보드가 존재하는
     형태로 구성되어 있다.

   여기서 프로젝트를 만들고 밑에 캔버스를 만들수도 있고
     만들어진 프로젝트내에 캔버스를 추가할 수도 있고
    
   탭중에 공유 캔버스를 선택시 다른이가 작성한 캔버스를
     볼수도 있다.

   캔버스중 하나를 클릭하면

    위와 같이 몇가지 도구를 제공하고 빈 화면을 제공한다.
      누군가가 열심히 작성하여 내용을 팀원들이 공유하면 끝

    공유를 위해서는 

    캔버스 위의 공유하기 버튼을 누른뒤 해당 링크를 공유하면 된다.
       상단의 공유시 권한도 부여가능하다.
  

3. 결론
   화이트 보드로 그리기 좋은 느낌은 살릴 수 없지만
     (화이트 보드로 업무를 공유하는 주된 이유가 뭔가
       빈 화면에 만들어내는 느낌 아닐까?)
   같은 내용을 팀원들 모두 확인 가능하고 
     다른 장소에서도 확인할 수 있다는 점은 강점으로 보임
     

2015년 11월 2일 월요일

클래스 디자인 패턴 21. Memento Pattern

1. 개념
  1) 의미
     문서 편집이나 그림 작업시 이전 상태로 되돌리기 위해서는
       이전 상태에 대한 정보가 남아 있어야 됩니다.
     Memento 패턴은 이전 상태를 담아두되
       인스턴트 상태를 나타내는 역할을 부여해 보존, 복원이
       실행되도록 하는 패턴입니다.


2. 소스

  1) Memento class
       현재 상태를 표현하는 클래스입니다.
package game;
import java.util.Vector;

public class Memento {
    int money;                  
         // 돈
    Vector fruits;            
        // 과일
    public int getMoney() {
       // 돈을 얻는다.(narrow interface)
        return money;
    }
    Memento(int money) {
       // 생성자(wide interface)
        this.money = money;
        this.fruits = new Vector();
    }
    void addFruit(String fruit) {
       // 과일을 추가한다.(wide interface)
        fruits.add(fruit);
    }
}


  2) Gamer 클래스
      현재 뭔가 작업이 이루어지는 클래스
      여기에서는 난수 및 시간을 딜레이 하는 기능을 이용해
      일정 시간별로 한 사이클씩 작업이 이루어집니다.

package game;
import java.util.Vector;
import java.util.Iterator;
import java.util.Random;

public class Gamer {
    private int money;                          // 소유한 돈
    private Vector fruits = new Vector();       // 과일
    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) {                            // 1이 나온다...돈이 증가한다.
            money += 100;
            System.out.println("돈이 증가했습니다.");
        } else if (dice == 2) {                     // 2가 나온다...돈이 반으로 준다.
            money /= 2;
            System.out.println("돈이 반으로 줄었습니다.");
        } else if (dice == 6) {                     // 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) {       // undo를 실행한다.
        this.money = memento.money;
        this.fruits = memento.fruits;
    }
    public String toString() {                      // 문자열 표현
        return "[money = " + money + ", fruits = " + fruits + "]";
    }
    private String getFruit() {                     // 과일을 1개 얻는다.
        String prefix = "";
        if (random.nextBoolean()) {
            prefix = "맛있다.";
        }
        return prefix + fruitsname[random.nextInt(fruitsname.length)];
    }
}



  3) 테스트 메인소스를 작성합니다.
      여기서는 작업이 진행된 상태를 사이클이 지날때마다
      보여주는 작업도 같이 합니다.
import game.Memento;
import game.Gamer;

public class Main {
    public static void main(String[] args) {
        Gamer gamer = new Gamer(100);               // 처음의 돈은 100
        Memento memento = gamer.createMemento();    // 처음의 상태를 보존해 둔다.
        for (int i = 0; i < 100; i++) {
            System.out.println("==== " + i);        // 횟수 표시
            System.out.println("현 상태:" + gamer);    // 현재의 주인공의 상태 표시

            gamer.bet();    // 게임을 진행 시킨다.

            System.out.println("돈은" + gamer.getMoney() + "원이 되었습니다.");

            // Memento의 취급 결정
            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) {
            }
            System.out.println("");
        }
    }
}


결과 :
==== 0
현 상태:[money = 100, fruits = []]
아무일도 일어나지 않았습니다.
돈은100원이 되었습니다.

==== 1
현 상태:[money = 100, fruits = []]
아무일도 일어나지 않았습니다.
돈은100원이 되었습니다.

==== 2
현 상태:[money = 100, fruits = []]
아무일도 일어나지 않았습니다.
돈은100원이 되었습니다.

==== 3
현 상태:[money = 100, fruits = []]
아무일도 일어나지 않았습니다.
돈은100원이 되었습니다.
1
==== 4
현 상태:[money = 100, fruits = []]
돈이 증가했습니다.
돈은200원이 되었습니다.
    (많이 증가했으니 현재의 상태를 보존해두자)

==== 5
현 상태:[money = 200, fruits = []]
과일(맛있다.포도)을 받았습닏다.
돈은200원이 되었습니다.

==== 6
현 상태:[money = 200, fruits = [맛있다.포도]]
과일(귤)을 받았습닏다.
돈은200원이 되었습니다.

........


3. 다이어그램

https://en.wikipedia.org/wiki/Memento_pattern

http://scotty83.tistory.com/entry/Memento-Pattern

4. 관련패턴
  1) Command 패턴
      undo, redo를 Memento 패턴을 사용해서 구현가능합니다.

  2) Prototype 패턴
    스냅샷 및 undo 기능을 추가하기 위해 Memento 패턴을
      넣을 수 있습니다.

  3) State 패턴
    상태를 포현한다는 점에선 같으나 State는 클래스 자체가 상태를
      표현하며 Memento는 인스턴스가 상태를 표현합니다.

클래스 디자인 패턴 20. Mediater Pattern

1. 개념
  1) 의미
     공동작업시 공유된 자원을 조정하는 조정자 역할을 하는 패턴
       상호간에 통신이 필요할때 꼭 조정자로 지정한 객체를 통해서
       통신하도록 정보를 집중하는 패턴
       GUI 에서 많이 사용함


2. 소스

  1) Mediattor 인터페이스
      해당 인터페이스는 조정자 역할을 담당할 클래스의
      interface를 정의합니다.
     이를 구현한 구현체는 LoginFrame이라는 클래스로 구현합니다.

public interface Mediator {
    public abstract void createColleagues();
    public abstract void colleagueChanged(Colleague colleague);
}


import java.awt.Frame;
import java.awt.Label;
import java.awt.Color;
import java.awt.CheckboxGroup;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class LoginFrame extends Frame implements ActionListener, Mediator {
    private ColleagueCheckbox checkGuest;
    private ColleagueCheckbox checkLogin;
    private ColleagueTextField textUser;
    private ColleagueTextField textPass;
    private ColleagueButton buttonOk;
    private ColleagueButton buttonCancel;

    // 생성자
    // Colleague들을 생성해서 배치한 후에 표시를 실행한다.
    public LoginFrame(String title) {
        super(title);
        setBackground(Color.lightGray);
        // 레이아웃 매니저를 사용해서 4*2의 그리드를 만든다.
        setLayout(new GridLayout(4, 2));
        // Colleague들의 생성
        createColleagues();
        // 배치
        add(checkGuest);
        add(checkLogin);
        add(new Label("Username:"));
        add(textUser);
        add(new Label("Password:"));
        add(textPass);
        add(buttonOk);
        add(buttonCancel);
        // 유효/무효의 초기지정
        colleagueChanged(checkGuest);
        // 표시
        pack();
        show();
    }

    // Colleague들을 생성한다.
    public void createColleagues() {
        // 생성
        CheckboxGroup g = new CheckboxGroup();
        checkGuest = new ColleagueCheckbox("Guest", g, true);
        checkLogin = new ColleagueCheckbox("Login", g, false);
        textUser = new ColleagueTextField("", 10);
        textPass = new ColleagueTextField("", 10);
        textPass.setEchoChar('*');
        buttonOk = new ColleagueButton("OK");
        buttonCancel = new ColleagueButton("Cancel");
        // Mediator의 세트
        checkGuest.setMediator(this);
        checkLogin.setMediator(this);
        textUser.setMediator(this);
        textPass.setMediator(this);
        buttonOk.setMediator(this);
        buttonCancel.setMediator(this);
        // Listener의 세트
        checkGuest.addItemListener(checkGuest);
        checkLogin.addItemListener(checkLogin);
        textUser.addTextListener(textUser);
        textPass.addTextListener(textPass);
        buttonOk.addActionListener(this);
        buttonCancel.addActionListener(this);
    }

    // Colleague로부터의 통지로 각 Colleague의 유효/무효를 판정한다.
    public void colleagueChanged(Colleague c) {
        if (c == checkGuest || c == checkLogin) {
            if (checkGuest.getState()) {             // Guest 모드
                textUser.setColleagueEnabled(false);
                textPass.setColleagueEnabled(false);
                buttonOk.setColleagueEnabled(true);
            } else {                                 // Login 모드
                textUser.setColleagueEnabled(true);
                userpassChanged();
            }
        } else if (c == textUser || c == textPass) {
            userpassChanged();
        } else {
            System.out.println("colleagueChanged:unknown colleague = " + c);
        }
    }
    // textUser 또는 textPass의 변경이 있었다.
    // 각 Colleague의 유효/무효를 판정한다.
    private void userpassChanged() {
        if (textUser.getText().length() > 0) {
            textPass.setColleagueEnabled(true);
            if (textPass.getText().length() > 0) {
                buttonOk.setColleagueEnabled(true);
            } else {
                buttonOk.setColleagueEnabled(false);
            }
        } else {
            textPass.setColleagueEnabled(false);
            buttonOk.setColleagueEnabled(false);
        }
    }
    public void actionPerformed(ActionEvent e) {
        System.out.println("" + e);
        System.exit(0);
    }
}


  2) Colleague 인터페이스 및 구현체들
      해당 구현체는 Mediator에게 뭔가 정보를 요구하거나
      정보를 요청하는 사용자들입니다.

public interface Colleague {
    public abstract void setMediator(Mediator mediator);
    public abstract void setColleagueEnabled(boolean enabled);
}


import java.awt.Button;

public class ColleagueButton extends Button implements Colleague {
    private Mediator mediator;
    public ColleagueButton(String caption) {
        super(caption);
    }
    public void setMediator(Mediator mediator) {            // Mediator를 보관
        this.mediator = mediator;
    }
    public void setColleagueEnabled(boolean enabled) {      // Mediator가 유효/무효를 지시한다.
        setEnabled(enabled);
    }
}


import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;

public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague {
    private Mediator mediator;
    public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) {  // 생성자
        super(caption, group, state);
    }
    public void setMediator(Mediator mediator) {            // Mediator를 보관
        this.mediator = mediator;
    }
    public void setColleagueEnabled(boolean enabled) {      // Mediator가 유효/무효를 지시한다.
        setEnabled(enabled);
    }
    public void itemStateChanged(ItemEvent e) {             // 상태가 변하면 Mediator에게 통지
        mediator.colleagueChanged(this);
    }
}


import java.awt.TextField;
import java.awt.Color;
import java.awt.event.TextListener;
import java.awt.event.TextEvent;

public class ColleagueTextField extends TextField implements TextListener, Colleague {
    private Mediator mediator;
    public ColleagueTextField(String text, int columns) {
        // 생성자
        super(text, columns);
    }
    public void setMediator(Mediator mediator) {
       // Mediator를 보관
        this.mediator = mediator;
    }
    public void setColleagueEnabled(boolean enabled) {
      // Mediator가 유효/무효를 지시한다.
        setEnabled(enabled);
        setBackground(enabled ? Color.white : Color.lightGray);
    }
    public void textValueChanged(TextEvent e) {
     // 문자열이 변하면 Mediator에게 통지
        mediator.colleagueChanged(this);
    }
}


  3) 테스트 메인소스를 작성합니다.
public class Main {
    static public void main(String args[]) {
        new LoginFrame("Mediator Sample");
    }
}



결과 :



3. 다이어그램

https://en.wikipedia.org/wiki/Mediator_pattern

http://copynull.tistory.com/145

4. 관련패턴
  1) Facade 패턴
      Mediatro 가 양방향 중재자로서 인터페이스를 제공했다면
      Facade는 단방향으로 정보를 제공합니다.

  2) Observer 패턴
      통신 자체는 Observer 패턴을 이용해서 수행되는 경우가 있습니다.

2015년 10월 26일 월요일

예술 영화관 (Art Theater) 위치 및 각 홈페이지(예매 및 시간표 확인)

게시물 작성시 참고한 페이지
     SEOUL ART THEATER MAP (링크 미확인 유인물)
 
     서울 예술극장 위키
     https://namu.wiki/w/%EC%98%88%EC%88%A0%EC%98%81%ED%99%94%EA%B4%80

     서울의 예술영화관
     https://ko.foursquare.com/breezeblow/list/%EC%84%9C%EC%9A%B8%EC%9D%98-%EC%98%88%EC%88%A0%EC%98%81%ED%99%94%EA%B4%80



1. CGV 아트 하우스(무비꼴라주)
  1) 위치 및 상영시간 (전용극장 이외에는 전용관을 운영중)
    (1) 아트하우스 상암
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0014&onlyOne=91

    (2) 아트하우스 신촌아트레온
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0150&onlyOne=91

    (3) 아트하우스 명동역(전용극장)
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0105&onlyOne=91

    (4) 아트하우스 대학로
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0063&onlyOne=91

    (5) 아트하우스 강변
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0001&onlyOne=91

    (6) 아트하우스 구로
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0010&onlyOne=91

    (7) 아트하우스 여의도
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0112&onlyOne=91

    (8) 아트하우스 소풍
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0143&onlyOne=91

    (9) 아트하우스 인천
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0002&onlyOne=91

    (10) 아트하우스 압구정(전용극장)
      ▶위치
      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0040&onlyOne=91

    (11) 아트하우스 오리
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0004&onlyOne=91

    (12) 아트하우스 동수원
      ▶위치


      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0041&onlyOne=91


    (13) 아트하우스 서면(부산)
      ▶위치
      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0005&onlyOne=91

    (13) 아트하우스 센텀시티(부산)
      ▶위치
      ▶상영시간
http://section.cgv.co.kr/theater/MovieCollage/TheaterTime/Default.aspx?theaterCode=0089&onlyOne=91

  2) 홈페이지
     http://www.cgv.co.kr/arthouse/


2. KT&G 상상마당 시네마
  1) 위치 및 상영시간 (홍대기준)
      ▶위치


      ▶상영시간
https://www.sangsangmadang.com/cinema/schedule/sheduleDate.asp

  2) 홈페이지
     www.sangsangmadang.com


3. KU시네마테크
  1) 위치 및 상영시간
      ▶위치
     서울시 광진구 능동로 120


      ▶상영시간
http://www.kucine.kr/index/index.php

  2) 홈페이지
    http://www.kucine.kr/index/index.php


4. KU시네마트랩
  1) 위치(고대내 위치) 및 상영시간
      ▶위치


      ▶상영시간
http://kucinetrap.kr/index/index.php

  2) 홈페이지
    http://www.kucinetrap.kr/index/index.php


5. 롯데시네마 아르떼
  1) 위치 및 상영시간
    (1) 아르떼 건대입구
      ▶위치


      ▶상영시간
http://www.lottecinema.co.kr/LHS/LHFS/Contents/CinemaInfo/ArteSchedule.aspx?CinemaGroupCode=0010&CinemaCode=1004&ScreenType=400

    (2) 아르떼 부평
      ▶위치


      ▶상영시간
http://www.lottecinema.co.kr/LHS/LHFS/Contents/CinemaInfo/ArteSchedule.aspx?CinemaGroupCode=0010&CinemaCode=3003&ScreenType=400

    (3) 아르떼 신도림
      ▶위치


      ▶상영시간
http://www.lottecinema.co.kr/LHS/LHFS/Contents/CinemaInfo/ArteSchedule.aspx?CinemaGroupCode=0010&CinemaCode=1015&ScreenType=400

    (4) 아르떼 오투(부산대)
      ▶위치


      ▶상영시간
http://www.lottecinema.co.kr/LHS/LHFS/Contents/CinemaInfo/ArteSchedule.aspx?CinemaGroupCode=0010&CinemaCode=2011&ScreenType=400

    (5) 아르떼 주엽(일산)
      ▶위치


      ▶상영시간
http://www.lottecinema.co.kr/LHS/LHFS/Contents/CinemaInfo/ArteSchedule.aspx?CinemaGroupCode=0010&CinemaCode=3013&ScreenType=400

    (6) 아르떼 청주
      ▶위치


      ▶상영시간
http://www.lottecinema.co.kr/LHS/LHFS/Contents/CinemaInfo/ArteSchedule.aspx?CinemaGroupCode=0010&CinemaCode=4003&ScreenType=400

  2) 홈페이지
    http://www.lottecinema.co.kr/LHS/LHFS/Contents/CinemaInfo/ArteNowMovie.aspx?CinemaGroupCode=0010&CinemaCode=1004&ScreenType=400


6. 미로스페이스
  1) 위치 및 상영시간
     서울특별시 종로구 경희궁1길 1 가든플레이스빌딩 2층
      ▶위치

      ▶상영시간(블로그로 일일 업로드)
         https://www.facebook.com/mirospace1

  2) 홈페이지(없음)
    (1) 블로그 및 카페 주소
        http://www.mirospace.co.kr/
    (2) 페이스북 등 SNS
        https://www.facebook.com/mirospace1


7. 서울아트시네마
  1) 위치 및 상영시간
      ▶위치


      ▶상영시간(달력 같은 스케쥴러가 있지만 2013.5 이후로는 업데이트x)


  2) 홈페이지
     http://www.cinematheque.seoul.kr/
    ps. 시간표가 따로 없음. 맥스무비,yes24, 티켓링크에서 가능


8. 스폰지하우스 광화문
  1) 위치 및 상영시간
      ▶위치


      ▶상영시간(트윗)
         https://twitter.com/spongehouse?lang=ko

  2) 홈페이지(없음)
    (1) 블로그 및 카페 주소
       http://cafe.naver.com/spongehouse.cafe


9. 씨네코드 선재(2015.11.30 폐관예정)
  1) 위치 및 상영시간
      ▶위치


      ▶상영시간


  2) 홈페이지(없음)
    (1) 블로그 및 카페 주소
        http://cafe.naver.com/artsonjearthall


10. 아리랑시네센터
  1) 위치 및 상영시간
     http://cine.arirang.go.kr/cine/intro/map.jsp

      ▶상영시간
http://cine.arirang.go.kr/cine/movie/movie_month.jsp

  2) 홈페이지
     http://cine.arirang.go.kr/cine/index.jsp


11. 씨네큐브
  1) 위치 및 상영시간
      ▶위치
 

      ▶상영시간
http://www.icinecube.com/movie/list.jsp?flag=1
  
  2) 홈페이지
      http://www.icinecube.com/


12. 아트나인
  1) 위치 및 상영시간
      ▶위치

      http://cafe.naver.com/minitheaterartnine.cafe?iframe_url=/ArticleList.nhn%3Fsearch.clubid=25494727%26search.menuid=29%26search.boardtype=B

      ▶상영시간(네이버카페 게시판으로 관리)
http://cafe.naver.com/minitheaterartnine.cafe?iframe_url=/ArticleList.nhn%3Fsearch.clubid=25494727%26search.menuid=29%26search.boardtype=B


  2) 홈페이지(네이버카페 및 메가박스로 안내)
      www.artnine.co.kr


13. 아트하우스 모모
  1) 위치 및 상영시간
      ▶위치
     서울시 서대문구 대현동 11-1

     홈페이지 오시는길 안내
     http://www.arthousemomo.com/direction

      ▶상영시간
http://arthousemomo.com/screen_current/

  2) 홈페이지
     http://www.arthousemomo.com/


14. 영화공간주안
  1) 위치 및 상영시간
      ▶위치
      http://www.cinespacejuan.com/aboutus/location.php

      ▶상영시간
http://www.cinespacejuan.com/movie/

  2) 홈페이지
      http://www.cinespacejuan.com/


15. 인디스페이스
  1) 위치 및 상영시간
      ▶위치
      http://indiespace.tistory.com/notice/1005

      ▶상영시간
http://indiespace.kr/category/Now%20Playing

  2) 홈페이지
      http://www.indiespace.kr/


16. 필름포럼
  1) 위치 및 상영시간
      ▶위치
 

      ▶상영시간
구글에서 처리한 결과를 보여준다고 합니다. 여기에 상영시간이 표시되요

  2) 홈페이지
      http://www.filmforum.kr/

2015년 10월 25일 일요일

클래스 디자인 패턴 19. Chain of Responsibility Pattern

1. 개념
  1) 의미
     같은 입력부분의 내용에 따라 출력에 대해 다른 객체
       로 작업하여 보내야 하는 경우, 해당 패턴을 이용해서
       매칭되는 객체를 찾아서 결과를 낼수 있는 방법입니다.
     이때 사슬처럼 쭉 연결해 놓고 적절성 유무를 판단후 다음 객체로
       넘기기 때문에 체인이라 이름붙었습니다.

     좋은점은 입력시에 결과에 어떤 객체를 사용할지 생각하지 않고
       쓸수 있습니다.
      단점은 속도 문제는 있을수 있습니다.


2. 소스

  1) Trouble는 발생한 문제를 표현합니다.

public class Trouble {
    private int number;             // 트러블 번호
    public Trouble(int number) {    // 트러블의 생성
        this.number = number;
    }
    public int getNumber() {        // 트러블 번호를 얻는다.
        return number;
    }
    public String toString() {      // 트러블의 문자열 표현
        return "[Trouble " + number + "]";
    }
}


  2) Support 클래스는 발생한 문제에 대한 해결을 위해
       구현할 클래스입니다.

public abstract class Support {
    private String name;                    // 트러블 해결자의 이름
    private Support next;                   // 떠넘기는 곳
    public Support(String name) {           // 트러블 해결자의 생성
        this.name = name;
    }
    public Support setNext(Support next) {  // 떠넘길 곳을 설정
        this.next = next;
        return next;
    }
    public final void support(Trouble trouble) {  // 트러블 해결 순서
        if (resolve(trouble)) {
            done(trouble);
        } else if (next != null) {
            next.support(trouble);
        } else {
            fail(trouble);
        }
    }
    public String toString() {              // 문자열 표현
        return "[" + name + "]";
    }
    protected abstract boolean resolve(Trouble trouble); // 해결용 메소드
    protected void done(Trouble trouble) {  // 해결
        System.out.println(trouble + " is resolved by " + this + ".");
    }
    protected void fail(Trouble trouble) {  // 미해결
        System.out.println(trouble + " cannot be resolved.");
    }
}


  3) 서포트를 상속하여 연결 대상이 되는 클래스를
       작성합니다.

public class NoSupport extends Support {
    public NoSupport(String name) {
        super(name);
    }
    protected boolean resolve(Trouble trouble) {     // 해결용 메소드
        return false; // 자신은 아무 처리도 하지 않는다.
    }
}


public class LimitSupport extends Support {
    private int limit;                              // 이 번호 미만이면 해결 할수 있다.
    public LimitSupport(String name, int limit) {   // 생성자
        super(name);
        this.limit = limit;
    }
    protected boolean resolve(Trouble trouble) {         // 해결용 메소드
        if (trouble.getNumber() < limit) {
            return true;
        } else {
            return false;
        }
    }
}


public class OddSupport extends Support {
    public OddSupport(String name) {                // 생성자
        super(name);
    }
    protected boolean resolve(Trouble trouble) {    // 해결용 메소드
        if (trouble.getNumber() % 2 == 1) {
            return true;
        } else {
            return false;
        }
    }
}


public class SpecialSupport extends Support {
    private int number;                                 // 이 번호만 해결할 수 있다.
    public SpecialSupport(String name, int number) {    // 생성자
        super(name);
        this.number = number;
    }
    protected boolean resolve(Trouble trouble) {     // 해결용 메소드 
        if (trouble.getNumber() == number) {
            return true;
        } else {
            return false;
        }
    }
}


  4) 테스트 메인소스를 작성합니다.
public class Main {
    public static void main(String[] args) {
        Support alice   = new NoSupport("Alice");
        Support bob     = new LimitSupport("Bob", 100);
        Support charlie = new SpecialSupport("Charlie", 429);
        Support diana   = new LimitSupport("Diana", 200);
        Support elmo    = new OddSupport("Elmo");
        Support fred    = new LimitSupport("Fred", 300);
        // 연쇄의 형성
        alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);
        // 다양한 트러블 발생
        for (int i = 0; i < 500; i += 33) {
            alice.support(new Trouble(i));
        }
    }
}


결과 :
[Trouble 0] is resolved by [Bob].
[Trouble 33] is resolved by [Bob].
[Trouble 66] is resolved by [Bob].
[Trouble 99] is resolved by [Bob].
[Trouble 132] is resolved by [Diana].
[Trouble 165] is resolved by [Diana].
[Trouble 198] is resolved by [Diana].
[Trouble 231] is resolved by [Elmo].
[Trouble 264] is resolved by [Fred].
[Trouble 297] is resolved by [Elmo].
[Trouble 330] cannot be resolved.
[Trouble 363] is resolved by [Elmo].
[Trouble 396] cannot be resolved.
[Trouble 429] is resolved by [Charlie].
[Trouble 462] cannot be resolved.
[Trouble 495] is resolved by [Elmo].


3. 다이어그램
https://ko.wikipedia.org/wiki/Chain_of_responsibility_%ED%8C%A8%ED%84%B4

https://sourcemaking.com/design_patterns/chain_of_responsibility


4. 관련패턴
  1) Composite pattern

  2) Command Pattern