2012년 5월 10일 목요일

[JAVA_Security]Java(자바) 데이터 암호화 XOR

@ 데이터 암호화를 위해 논리 연산의 XOR를 상용한 소스이다.


 public class XorSample  
 {  
   public final static byte[] KEY = "4d2dg".getBytes( );  
   public static void main( String[] args )  
   {  
     XorSample sample = new XorSample( );  
     sample.exec( );  
   }  
   public void exec( )  
   {  
     StringBuffer data = new StringBuffer( );  
     for ( int i = 0 ; i < 30 ; i++ )  
     {  
       data.append( i );  
       data.append( "안녕하세요!" );  
       data.append( i );  
     }  
     byte[] encrypt = xor( data.toString( ).getBytes( ) , KEY );  
     System.out.println( encrypt.length );  
     System.out.println( "변환:" + new String( encrypt ) );  
     byte[] decrypt = xor( encrypt , KEY );  
     System.out.println( "재변환:" + new String( decrypt ) );  
     System.out.println( decrypt.length );  
   }  
   public byte[] xor( byte[] data , byte[] key )  
   {  
     final int orgLength = data.length;  
     final int keyLength = key.length;  
     final byte[] converted = new byte[orgLength];  
     for ( int i = 0 , j = 0 ; i < orgLength ; i++ , j++ )  
     {  
       converted[ i ] = ( byte ) ( data[ i ] ^ key[ j ] );  
       if ( j >= ( keyLength - 1 ) )  
       {  
         j = 0;  
       }  
     }  
     return converted;  
   }  
 }  

2012년 5월 7일 월요일

[Java Design Pattern_5]Singleton 샘플 코드1

Triple.java


package com.sgdata.singleton;

public class Triple {
private static Triple[] triple = new Triple[ ] {
new Triple(0) ,
new Triple(1) ,
new Triple(2) ,
};
private int id;
private Triple(int id){
System.out.println("The instance " + id + " is created. ");
this.id = id;
}
public static Triple getInstance(int id){
return triple[id];
}
public String toString(){
return "[Triple id=" + id + "]";
}
}

Main.java

package com.sgdata.singleton;

public class Main {
public static void main(String[] args) {
System.out.println("Start");
for(int i=0;i<9;i++){
Triple triple = Triple.getInstance(i%3);
System.out.println(i+":"+triple);
}
System.out.println("End.");
}

}

[Java Design Pattern_4]Factory Method 샘플 코드2


1. Framework

- Product  클래스 : '제품'을 표현한 추상 클래스로서 추상 메서드 use만 선언 되어 있다.


package com.sgdata.factorymethod;
 
public abstract class Product {
     public abstract void use();
}


- Factory 클래스 : 템플릿 패턴이 적용되어 있습니다. 추상 메서드                                                    createProduct,registerProduct는 하위 클래스에서 구현 합니다. 


package com.sgdata.factorymethod;

public abstract class Factory {
    public final Product create(String owner) {
         Product p = createProduct(owner);
         registerProduct(p);
         return p;
    }
    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(Product product);
}



2. Idcard

- IDCard 클래스 : Product 클래스를 상속받아서 구현.


package com.sgdata.factorymethod;

public class IDCard extends Product{

private String owner;
private int serial;

IDCard(String owner, int serial){
System.out.println(owner +"("+serial+")"+"의 카드를 만듭니다.");
this.owner = owner;
this.serial = serial;
}

@Override
public void use() {
// TODO Auto-generated method stub
System.out.println(owner + "(" + serial +")" +"의 카드를 사용합니다.");
}
public String getOwner(){
return owner;
}
public int getSerial(){
return serial;
}
}


- IDCardFactory : Factory 클래스를 상속받아서 구현.

package com.sgdata.factorymethod;

import java.util.HashMap;
import java.util.Hashtable;

public class IDCardFactory extends Factory{

private HashMap database = new HashMap();
private int serial = 100;
@Override
protected synchronized Product createProduct(String owner) {
// TODO Auto-generated method stub
return new IDCard(owner, serial++);
}
@Override
protected void registerProduct(Product product) {
// TODO Auto-generated method stub
IDCard card = (IDCard)product;
database.put(new Integer(card.getSerial()), card.getOwner());
}
public HashMap getDatabase(){
return database;
}
}

3. Main

package com.sgdata.factorymethod;

public class Main {  
     public static void main(String[] args) {  
          Factory factory = new IDCardFactory();  
          Product card1 = factory.create("홍길동");  
          Product card2 = factory.create("김민수");  
          Product card3 = factory.create("구로이드");  
          card1.use();  
          card2.use();  
          card3.use();  
     }  

2012년 4월 26일 목요일

[Java Design Pattern_3]Template Method 샘플 코드2


@ AbstractClass (추상 클래스)  

 - 이 클래스에서는 탬플릿 메소드를 구현(정의)합니다.


package Template;

public abstract class AbstractDisplay {
public final void decorate(){
   char topChar = getTopCharacter();
   char leftChar = getLeftCharacter();
   String str = getString();
   char rightChar = getRightCharacter();
   char bottomChar = getBottomCharacter();

   for(int i=0; i<str.length() + 2; i++){
       System.out.print(topChar);
   }
   System.out.println();

   System.out.print(leftChar);
   if (isUpperCase()){
       System.out.print(str.toUpperCase());
   }else{
       System.out.print(str.toLowerCase());
   }

   System.out.print(rightChar);

   System.out.println();
   for(int i=0; i<str.length() + 2; i++){
   System.out.print(bottomChar);
   }
}

protected boolean isUpperCase() {
return true;
}

protected abstract char getTopCharacter();

protected abstract char getLeftCharacter();

protected abstract String getString();

protected abstract char getRightCharacter();

protected abstract char getBottomCharacter();
}

@ ConcreateClass(구현 클래스)

-  추상 클래스에서 정의된 메소드를 구체적으로 구현 합니다.

package Template;

public class StringDisplay extends AbstractDisplay {
    @Override
    protected char getBottomCharacter() {
        return '#';
    }
    @Override
    protected char getLeftCharacter() {
        return '(';
    }
    @Override
    protected char getRightCharacter() {
        return ')';
    }
    @Override
    protected String getString() {
        return "sgdata";
    }
    @Override
    protected char getTopCharacter() {
        return '#';
    }
}

@ Main Class

package Template;

public class Main {
public static void main(String[] args) {
    AbstractDisplay decorator = new StringDisplay();
        decorator.decorate();
    }
}

2012년 4월 24일 화요일

[Java Design Pattern_5]Singleton 설명

# Singleton
-  인스턴스를 한 개만 만들기

@ Singleton 패턴

- '클래스의 인스턴스가 단 하나만 필요'한 경우에 사용하는 패턴.
- 컴퓨터 자체를 표현한 클래스, 현재의 시스템 설졍을 표현한 클래스, 윈도우 시스템을 표현한 클래스..











[Java Design Pattern_4]Factory Method 샘플 코드1





1. Framework

 - Product  클래스 : '제품'을 표현한 추상 클래스로서 추상 메서드 use만 선언 되어 있다.

 package sample.framework;  
 public abstract class Product {  
      public abstract void use();  
 }  


- Factory 클래스 : 템플릿 패턴이 적용되어 있습니다. 추상 메서드 createProduct,registerProduct는 하위 클래스에서 구현 합니다. create 메서드는 Product의 인스턴스를 생성하는 것으로 규정하고 있습니다. 즉, createProduct에서 제품을 만들어서 registerProduct에서 등록한다고 규정하고 있습니다.

 package sample.framework;  
 public abstract class Factory {  
      public final Product create(String owner) {  
           Product p = createProduct(owner);  
           registerProduct(p);  
           return p;  
      }  
      protected abstract Product createProduct(String owner);  
      protected abstract void registerProduct(Product product);  
 }  


2. Idcard

- IDCard 클래스 : Product 클래스를 상속받아서 구현.

 package sample.idcard;  
 import sample.framework.Product;  
 public class IDCard extends Product {  
      private String owner;  
      IDCard(String owner) {  
           System.out.println(owner + "의 카드를 만듭니다.");  
           this.owner = owner;  
      }  
      public void use() {  
           System.out.println(owner + "�̃의 카드를 사용합니다.");  
      }  
      public String getOwner() {  
           return owner;  
      }  
 }  


- IDCardFactory : Factory 클래스를 상속받아서 구현.

 package sample.idcard;  
 import java.util.ArrayList;  
 import java.util.List;  
 import sample.framework.Factory;  
 import sample.framework.Product;  
 public class IDCardFactory extends Factory {  
      private List owners = new ArrayList();  
      protected Product createProduct(String owner) {  
           return new IDCard(owner);  
      }  
      protected void registerProduct(Product product) {  
           owners.add(((IDCard) product).getOwner());  
      }  
      public List getOwners() {  
           return owners;  
      }  
 }  



3. Main

 package sample;  
 import sample.framework.Factory;  
 import sample.framework.Product;  
 import sample.idcard.IDCardFactory;  
 public class Main {  
      public static void main(String[] args) {  
           Factory factory = new IDCardFactory();  
           Product card1 = factory.create("홍길동");  
           Product card2 = factory.create("김민수");  
           Product card3 = factory.create("구로이드");  
           card1.use();  
           card2.use();  
           card3.use();  
      }  
 }  






[Java Design Pattern_4]Factory Method 설명


# Factory Method
- 하위 클래스에서 인스턴스 작성하기


@ Factory Method 패턴

- Template Method 패턴을 인스턴스 생성에 적용한 것이 Factory Method패턴이다.

- 인스턴스 생성을 위한 골격(framework)와 실제의 인스턴스 생성의 클래스를 분리해서 생각할수 있습니다. 인스턴스를 만드는 방법을 상위 클래스 측에서 결정, 구체적인 내용은 모두 하위 클래스 측에서 수행합니다.


@ Factory Method 패턴의 등장인물

1. Framework

 - Product(제품)  : framework 쪽의 클래스로서 만들고자(생산)하는 클래스의 API를 결정하는 추상 클래스 입니다. 구체적인 내용은 ConcreteProduct에서 구현합니다.

 - Creator(작성자) : Product를 생성하는 추상 클래스입니다. Creator가 가지고 있는 정보는 Product 역할과 인스턴스 생성 메소드뿐입니다.
  * new 를 사용해서 실제의 인스턴스를 생성하는 대신에, 인스턴스 생성을 위한 메소드를 호출해서 구체적인 클래스 이름에 의한 속박에서 상위 클래스를 자유롭게 만듭니다.

2. idcard(Concrete)

 - ConcreteProduct(구체적인 제품) : 구체적인 제품 클래스.

 - ConcreteCreator(구체적인 작성자) : 구체적인 제품을 만드는 클래스.


@예제

-  구조




1. Framework

 - Product  클래스 : '제품'을 표현한 추상 클래스로서 추상 메서드 use만 선언 되어 있다.

 - Factory 클래스 : 템플릿 패턴이 적용되어 있습니다. 추상 메서드  createProduct,registerProduct는 하위 클래스에서 구현 합니다. create 메서드는 Product의 인스턴스를 생성하는 것으로 규정하고 있습니다. 즉, createProduct에서 제품을 만들어서 registerProduct에서 등록한다고 규정하고 있습니다.

2. Idcard

- IDCard 클래스 : Product 클래스를 상속받아서 구현

- IDCardFactory : Factory 클래스를 상속받아서 구현.
                         (createProduct, registerProduct 메소드 구현)


3. Main

 - Main 클래스 : 실행 클래스


@ Think!!

 1. Framework와 Idcard 패키지를 의존하고 있지 않다.

- '추상적인 골격' '구체적인 내용'의 두가지 측면으로 Factory Method를 살펴 보았습니다. 위와 달리 IDCard외 Television을 만든다고 가정하면, TelevisionFactory 클래스(Factory 상속)와 Television 클래스(Product 상속)만 만들면 새로운 객체에 적용할 수 있습니다. 이때 Framework의 클래스(Factory, Product)는 수정할 수 필요가 없습니다.

2. 인스턴스 생성  - 메소드의 구현 방법(createProduct 메소드)

- 추상 메소드로 한다.

- 디폴트의 구현을 준비해 둔다. : 하위 클래스에서 구현하지 않았을 경우를 염두해 둔 코드. 이때 Product는 추상 클래스로 만들지 못한다.

- 에러를 이용한다.  : 하위 클래스가 구현하지 않으면 에러가 발생하도록 해둔 코드.
 [FactoryMethodRuntimeException은 별로 작성되어 있다고 가정]

[Java Design Pattern_2]Adapter 샘플 코드3_File 입출력

- Target(대상) : 상속의 경우 인터페이스로 원하는 API를 만든다.


package Adapter;


import java.io.IOException;


public interface FileIO {
public void readFromFile(String filename) throws IOException;
public void writeToFile(String filename) throws IOException;
public void setValue(String key, String value);
public String getValue(String key);
}


- Adaptee(개조되는 쪽) : 기존에 사용되고 있는 클래스로서 Target의 API에 맞게 재구현되는 클래스이다.


java.util.Properties


void load (InputStream in) throws IOException
: 속성의 집합을 InputStream에서 읽는다.


void store (OutputStream out, String header) throws IOException
: 속성의 집합을 OutputStream에 쓴다. header는 코멘트 문자열.


- Adapter(어댑터) : Adaptee와 Target을 이어주는 클래스이다.


1. 상속의 경우 타겟은 인터페이스로 Adaptee는 상속으로 받아서 변환시킨다.



package Adapter;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;


public class FileProperties extends Properties implements FileIO{
public void readFromFile(String filename) throws IOException{
load(new FileInputStream(filename));
}

public void writeToFile(String filename) throws IOException {
store(new FileOutputStream(filename), "written by FileProperties");
}

public void setValue(String key, String value) {
setProperty(key, value);
}

public String getValue(String key) {
return getProperty(key, "");
}
}


2. 위임의 경우 Target클래스를 상속해서 Adaptee 클래스 인스턴스로 구현시킨다.



package Adapter;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;


public class FileProperties implements FileIO{

private Properties properties;

public FileProperties(){
this.properties = new Properties();
}

public void readFromFile(String filename) throws IOException{
this.properties.load(new FileInputStream(filename));
}

public void writeToFile(String filename) throws IOException {
this.properties.store(new FileOutputStream(filename), "written by FileProperties");
}

public void setValue(String key, String value) {
this.properties.setProperty(key, value);
}

public String getValue(String key) {
return this.properties.getProperty(key, "");
}
}

- Client(의뢰자) : Target을 통해 일을 하는 클래스이다.



package Adapter;


import java.io.*;


public class Main {


public static void main(String[] args) {
FileIO f = new FileProperties();
try {
f.readFromFile("file.txt");
f.setValue("year", "2004");
f.setValue("month", "4");
f.setValue("day", "21");
f.writeToFile("newfile.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}




[Java Design Pattern_3]Template Method 샘플 코드1

@ AbstractClass (추상 클래스)  


 - 이 클래스에서는 탬플릿 메소드를 구현(정의)합니다.

 public abstract class AbstractDisplay {  
      public abstract void open();  
      public abstract void print();  
      public abstract void close();  
      public final void display() {  
           open();  
           for (int i = 0; i < 5; i++)  
                print();  
           close();  
      }  
 }  

@ ConcreateClass(구현 클래스)


-  추상 클래스에서 정의된 메소드를 구체적으로 구현 합니다.

1. CharDisplay


 public class CharDisplay extends AbstractDisplay {  
      char ch;  
      public CharDisplay(char ch) {  
           this.ch = ch;  
      }  
      @Override  
      public void open() {  
           System.out.print("<<");  
      }  
      @Override  
      public void print() {  
           System.out.print(ch);  
      }  
      @Override  
      public void close() {  
           System.out.println(">>");  
      }  
 }  


2. StringDisplay

 public class StringDisplay extends AbstractDisplay {  
      String str;  
      public StringDisplay(String str) {  
           this.str = str;  
      }  
      @Override  
      public void open() {  
           printLine();  
      }  
      @Override  
      public void print() {  
           System.out.println("|" + str + "|");  
      }  
      @Override  
      public void close() {  
           printLine();  
      }  
      private void printLine() {  
           System.out.print("+");  
           try {  
                for (int i = 0; i < str.getBytes("euc-kr").length; i++)  
                     System.out.print("-");  
                System.out.println("+" + str.getBytes("euc-kr").length);  
           } catch (Exception e) {  
           }  
      }  
 }  



@ Main Class

 public class Main {  
      public static void main(String[] args) {  
           AbstractDisplay d1=new CharDisplay('H');  
           AbstractDisplay d2=new StringDisplay("Hello, world");  
           AbstractDisplay d3=new StringDisplay("안녕하세요.");  
           d1.display();  
           d2.display();  
           d3.display();  
      }  
 }  



[Java Design Pattern_3]Template Method 설명


# Templete Method 

- 하위 클래스에서 구체적으로 처리하기



@ 템플릿이란 무엇인가 ?  


- 템플릿이란 문자 모양으로 구멍이 뚫려있는 얇은 플라스틱 판을 말합니다. 구멍에 어떤 펜을 쓰느냐에 따라 같은 템플릿(모양)에서도 다양한 느낌을 낼수 있습니다.


@ Template Method 패턴이란


 - Template Method 패턴은 상위 클래스쪽에 탬플릿에 해당하는 메소드가 정의(주로 추상 메서드)되어 있고, 하위 클래스에서 구체적으로 구현되는 것을 말합니다. 이와 같이 상위 클래스에서 처리의 뼈대를 결정하고, 하위 클래스에서 그 구체적인 내용을 결정하는 디자인 패턴을 Template Method패턴이라고 합니다.


@ Template Method 패턴의 등장인물


 - AbstractClass (추상 클래스) : 이 클래스에서는 탬플릿 메소드를 구현(정의)합니다.

 - ConcreteClass (구현 클래스) : 추상 클래스에서 정의된 메소드를 구체적으로 구현 합니다.


@ 예제 


 - 구조





- AbstractDisplay : 템플릿 메소드 구현 및 정의.
        구체적으로 구현 되지 않은 open(),print(),close() 메소드로 display 메소드만 구현 되어 있음.(open(),print(),close() 메소드 구현은 하위 클래스에 맡김.)

- CharDisplay, StringDisplay : open(),print(),close() 구현 하는 클래스

- Main : AbstractDisplay 객체를 생성해서 사용.



@ Think!


1. 로직을 공통화 할수 있어 수정이 용이하다.


 - 상위 클래스의 템플릿 메소드에서 알고리즘(display())이 기술되어 있으므로, 하위 클래스에서 알고리즘을 일일이 기술할 필요가 없다.

 - 만약 수정 사항이 생겨도 해당 구현 클래스만 수정하면 된다. 즉, 알고리즘 수정시 상위 클래스, 구현 수정시 하위 클래스만 수정하면 된다.


2. 상위 클래스와 하위 클래스의 연계


- 상위 클래스에서 선언된 추상 메소드를 실제적으로 하위 클래스에서 구현하므로 어떤 시점에 메소드가 호출되는지 이해해야 하위 클래스에서 잘 구현할수 있다.


3. 하위 클래스를 상위 클래스에 넣어 동작시킨다.

 상위 클래스인AbstractDisplay형의 변수에 하위 클래스인 CharDisplay,StringDisplay인스턴스를 넣어 상위 클래스 템플릿 메소드은 display()를 사용한다. 이처럼 특정 인스턴스로 형변환을 하지 않고 동작하도록 하므로 어떤 하위 클래스 인스턴스를 넣어도 작동할 수 있다.


- 상속의 일반적인 원칙 -

" 상위 클래스형의 변수에 하위 클래스의 어떠한 인스턴스를 대입해도 제대로 작동할 수 있도록 한다" 
- The Liskov Substitution Principle(LSP)












[Java Design Pattern_2]Adapter 샘플 코드2_상속을 통한 구현

@ 상속을 통한 Adapter 구현

- Target(대상) : 상속의 경우 인터페이스로 원하는 API를 만든다.

 public interface Print {  
      public abstract void printWeak();  
      public abstract void printStrong();  
 }  

- Adaptee(개조되는 쪽) : 기존에 사용되고 있는 클래스로서 Target의 API에 맞게 재구현되는 클래스이다.

 public class Banner {  
      private String string;  
      public Banner(String string) {  
           this.string = string;  
      }  
      public void showWithParen() {  
           System.out.println("(" + string + ")");  
      }  
      public void showWithAster() {  
           System.out.println("*" + string + "*");  
      }  
 }  

- Adapter(어댑터) : 상속의 경우 타겟은 인터페이스로 Adaptee는 상속으로 받아서 변환시킨다.

 public class PrintBanner extends Banner implements Print {  
   public PrintBanner(String string) {  
     super(string);  
   }  
   public void printWeak() {  
     showWithParen();  
   }  
   public void printStrong() {  
     showWithAster();  
   }  
 }  

- Client(의뢰자) : Target을 통해 일을 하는 클래스이다.

 public class Main {  
      public static void main(String[] args) {  
           Print p = new PrintBanner("Hello");  
           p.printWeak();  
           p.printStrong();  
      }  
 }  


2012년 4월 23일 월요일

[Java Design Pattern_1]Iterator 샘플 코드3_ ArrayList를 사용한 서가 프로그램


@ 기본 패턴

- Iterator(반복자) : interface Iterator

package Iterator;

public interface Iterator {
    public abstract Object next();
    public abstract boolean hasNext();
}

- Aggregate(집합체)   :  interface Aggregate

package Iterator;

public interface Aggregate {
    public abstract Iterator iterator();
    public abstract int getLength();
    public abstract Object getBookAt(int index);
}



@ 구현


- Element(요소) : Book

package Iterator;

public class Book {
     String name;
     public Book(String name) {
          this.name = name;
     }
     String getName(){
          return name;
     }
}

- ConcreteAggregate(구체적인 집합체) : BookShelf

package Iterator;

import java.util.ArrayList;

public class BookShelf implements Aggregate {
     private ArrayList<Book> books;
     public BookShelf() {
          this.books=new ArrayList<Book>();
     }
     public void appendBook(Book book){
          this.books.add(book);
     }
     public Book getBookAt(int index){
          return this.books.get(index);
     }
     public int getLength(){
          return this.books.size();
     }
     public boolean findBook(String name){
    int flag=0;
    for(int i=0;i<this.getLength();i++){
    if(this.getBookAt(i).getName().equalsIgnoreCase(name)){
    flag=1;
    }
    }    
    if(flag==1){
    return true;
    }else{
    return false;
    }
     }
     public Iterator iterator() {
          return new BookShelfIterator(this);
     }
}

- ConcreteIterator(구체적인 반복자) : BookShelfIterator

package Iterator;

public class BookShelfIterator implements Iterator {  
     private Aggregate bookShelf;  
     private int index;  
     public BookShelfIterator(Aggregate shelf) {  
          this.bookShelf = shelf;  
          index=0;  
     }  
     @Override  
     public Object next() {  
          Book book=(Book)bookShelf.getBookAt(index);  
          index++;  
          return book;  
     }   
     @Override  
     public boolean hasNext() {  
          if(index<bookShelf.getLength())  
               return true;  
          else  
               return false;  
     }  
}   

@ 실행

- Main

package Iterator;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {  
      public static void main(String[] args) throws NumberFormatException, IOException {  
           BookShelf bookShelf=new BookShelf(); 
           String name="";
           int value=0;
           BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
           while(true){
          System.out.println("책입력 1번");
          System.out.println("전체 책 출력 2번");
          System.out.println("책검색 3번");
          System.out.println("끝내기 4번");
          System.out.print(">> ");
          
          value = Integer.valueOf(br.readLine());
          
          if(value==1){
          System.out.print("책의 제목을 입력하시오 : ");
          name = br.readLine();
              bookShelf.appendBook(new Book(name));
              System.out.println();
          }else if(value==2){
          Iterator it=bookShelf.iterator();  
                   while(it.hasNext()){  
                        System.out.println(((Book)it.next()).getName());  
                   }
                   System.out.println("총 "+bookShelf.getLength()+"권이 서가에 존재합니다.");
                   System.out.println();
          }else if(value==3){
          System.out.print("검색을 원하는 책의 제목을 입력하시오 : ");
          name = br.readLine();
          if(bookShelf.findBook(name)==true){
          System.out.println("검색하신 책이 서가에 존재합니다.");
          }else{
          System.out.println("검색하신 책이 서가에 존재하지 않습니다.");
          }           
          System.out.println();
          }else if(value==4){
          System.out.println("서가 프로그램을 종료합니다.");  
          break;
          }else{           
          System.out.println("잘못된 숫자를 입력하셨습니다.");
          System.out.println();
          }          
           }         
      }  
 } 






2012년 4월 21일 토요일

[Java Design Pattern_2]Adapter 샘플 코드1_위임을 통한 구현


@ Target(대상)의 역할  - 위임의 경우 추상 클래스

 public abstract class Print {  
      public abstract void printWeak();  
      public abstract void printStrong();  
 }  


@ Adaptee(개조 되는 쪽) - 실제적인 기능 클래스로서 Target의 인터페이스에 맞춰서 변화될 클래스

 public class Banner {  
      private String string;  
      public Banner(String string) {  
           this.string = string;  
      }  
      public void showWithParen() {  
           System.out.println("(" + string + ")");  
      }  
      public void showWithAster() {  
           System.out.println("*" + string + "*");  
      }  
 }  


@ Adapter(어댑터)의 역할 - Adaptee와 Target을 이어주는 클래스이다. 위임의 경우 Target클래스를 상속해서 Adaptee 클래스 인스턴스로 구현.

 public class PrintBanner extends Print {  
   private Banner banner;  
   public PrintBanner(String string) {  
     this.banner = new Banner(string);  
   }  
   public void printWeak() {  
     banner.showWithParen();  
   }  
   public void printStrong() {  
     banner.showWithAster();  
   }  
 }  

@ Client (의뢰자)의 역할 - Adapter를 사용하는 Main 클래스

 public class Main {  
      public static void main(String[] args) {  
           Print p = new PrintBanner("Hello");  
           p.printWeak();  
           p.printStrong();  
      }  
 }  







[Java Design Pattern_2]Adapter 설명

# Adapter - 바꿔서 재이용하기


@ Adapter 패턴 - '이미 제공되어 있는 것'과 '필요한 것' 사이의 '차이'를 없애주는 디자인 패턴이 Adapter 패턴 입니다. 그래서 Adapter 패턴은  Wrapper 패턴으로 불리기도 합니다.

@ Adapter 패턴의 종류

 1. 클래스에 의한 Adapter 패턴 (상속을 사용한 Adapter 패턴)
 2. 인스턴스에 의한 Adapter 패턴(위임을 사용한 Adapter 패턴)


@ 상속을 사용한 Adapter 패턴


 - PrintBanner 클래스가 어댑터의 역할을 담당합니다. 이 클래스는 제공되어 있는 Banner 클래스를 상속해서, 필요로 하는 Print 인터페이스를 구현합니다. PrintBanner 클래스는 showWithParen(Banner) 메소드를 사용해서 printWeak(Print)를 구현하고, showWithAster(Banner) 메소드를 사용해서 printStrong(Print)를 구현합니다.


@ 위임을 사용한 Adapter 패턴

- PrintBanner 클래스는 banner 필드에서 Banner 클래스의 인스턴스를 가집니다. 이 인스턴스는 PrintBanner 클래스의 생성자에서 생성합니다. 그리고 printWeak 및 printStrong 메소드에서는 banner 필드를 매개로 showWithParen, showWithAster 메소드를 호출합니다. 즉, PrintBanner 클래스의 printWeak 메소드는 자신이 처리하는게 아니라 인스턴스(Banner)의 showWithParen 메소드에게 위임하고 있습니다.

@ Adapter 패턴의 등장 인물

 - Target(대상)의 역할 : Print 인터페이스(상속의 경우)나 Print 클래스(위임의 경우)가 이 역할을 합니다. Main 클래스가 사용하는 객체가 대상(Target)이다.

 - Client (의뢰자)의 역할 : 대상(Target)을 통해 일을 하는 Main 클래스가 이 역할을 한다.

 - Adaptee(개조되는 쪽)의 역할 : Banner 클래스가 이 역할을 한다. Banner 클래스의 역할이 Target의 메소드와 일치하면 Adapter의 역할이 필요없다.

 - Adapter의 역할 : PrintBanner 클래스가 Adapter 역할을 합니다. Banner클래스의 기능을 Target 대상이 사용할 수 있도록 상속,위임을 통해 구현한다.






@ 어떤 경우에 사용하는 것일까?

 1. 충분한 테스트를 받아서 버그가 적으며 실제로 지금까지 사용된 실적이 있는 클래스를 새로운 클라이언트 요청에 사용되도록 만들 때.

 2. 기존의 클래스를 전혀 수정하지 않고 목적한 인터페이스(API)를 맞출 때, 사용된다. 이때 기존 소스가 필요없다. 단지 사양(Signature..)만 알면 된다.

 3. 구 버전과 신 버전을 공존시키고, 유지와 보수도 편하게 하기 위해서 Adapter 패턴이 도움이 된다.












[Java Design Pattern_1]Iterator 샘플 코드2_집합체 변경





@ 기본 패턴


- Iterator(반복자) : interface Iterator


 package basic.pattern;  
 public interface Iterator {  
      public abstract Object next();  
      public abstract boolean hasNext();  
 }  


- Aggregate(집합체)   :  interface Aggregate


 package basic.pattern;  
 public interface Aggregate {  
           public abstract Iterator iterator();  
           public abstract int getLength();  
           public abstract Object getBookAt(int index);  
 }  

@ 구현


- Element(요소) : Book


 package Sample2;  
 public class Book {  
      String name;  
      public Book(String name) {  
           this.name = name;  
      }  
      String getName(){  
           return name;  
      }  
 }  


- ConcreteAggregate(구체적인 집합체)


1. BookShelfArrange.java


 package Sample2;  
 import basic.pattern.Aggregate;  
 import basic.pattern.Iterator;  
 public class BookShelfArrange implements Aggregate {  
      private Book[] books;  
      private int last=0;  
      public BookShelfArrange(int max) {  
           books=new Book[max];  
      }  
      public void appendBook(Book book){  
           this.books[last]=book;  
           last++;  
      }  
      public Book getBookAt(int index){  
           return books[index];  
      }  
      public int getLength(){  
           return last;  
      }  
      public Iterator iterator() {  
           // TODO Auto-generated method stub  
           return new BookShelfBackIterator(this);  
      }  
 }  


2. BookShelfList


 package Sample2;  
 import java.util.ArrayList;  
 import basic.pattern.Aggregate;  
 import basic.pattern.Iterator;  
 public class BookShelfList implements Aggregate {  
      private ArrayList<Book> books;  
      private int last=0;  
      public BookShelfList() {  
           books=new ArrayList<Book>();  
      }  
      public void appendBook(Book book){  
           books.add(book);  
           last++;  
      }  
      public Book getBookAt(int index){  
           return books.get(index);  
      }  
      public int getLength(){  
           return last;  
      }  
      public Iterator iterator() {  
           // TODO Auto-generated method stub  
           return new BookShelfBackIterator(this);  
      }  
 }  


- ConcreteIterator(구체적인 반복자)

1. BookShelfBackIterator


 package Sample2;  
 import basic.pattern.Aggregate;  
 import basic.pattern.Iterator;  
 public class BookShelfBackIterator implements Iterator {  
      private Aggregate bookShelf;  
      private int index;  
      public BookShelfBackIterator(Aggregate shelf) {  
           this.bookShelf = shelf;  
           index=0;  
      }  
      @Override  
      public Object next() {  
           Book book=(Book)bookShelf.getBookAt(index);  
           index++;  
           return book;  
      }  
      @Override  
      public boolean hasNext() {  
           if(index<bookShelf.getLength())  
                return true;  
           else  
                return false;  
      }  
 }  

@ 실행

- Main


 package Sample2;  
 import basic.pattern.Iterator;  
 public class Main {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
 //          BookShelfList bookShelf=new BookShelfList();  
           BookShelfArrange bookShelf=new BookShelfArrange(5);  
           bookShelf.appendBook(new Book("A"));  
           bookShelf.appendBook(new Book("B"));  
           bookShelf.appendBook(new Book("C"));  
           bookShelf.appendBook(new Book("D"));  
           bookShelf.appendBook(new Book("E"));  
           Iterator it=bookShelf.iterator();  
           while(it.hasNext()){  
                System.out.println(((Book)it.next()).getName());  
           }  
           System.out.println("End");  
      }  
 }  
*주석 부분만 바꾸면 집합체를 변경할 수 있다.







[Java Design Pattern_1]Iterator 샘플 코드1_반복자 변경




@ 기본 패턴


- Iterator(반복자) : interface Iterator


 package basic.pattern;  
 public interface Iterator {  
      public abstract Object next();  
      public abstract boolean hasNext();  
 }  


- Aggregate(집합체)   :  interface Aggregate


 package basic.pattern;  
 public interface Aggregate {  
           public abstract Iterator iterator();  
 }  


@ 구현


- Element(요소) : Book


 package Sample;  
 public class Book {  
      String name;  
      public Book(String name) {  
           this.name = name;  
      }  
      String getName(){  
           return name;  
      }  
 }  


- ConcreteAggregate(구체적인 집합체)


1. BookShelfArrange.java


 package Sample;  
 import basic.pattern.Aggregate;  
 import basic.pattern.Iterator;  
 public class BookShelfArrange implements Aggregate {  
      private Book[] books;  
      private int last=0;  
      public BookShelfArrange(int max) {  
           books=new Book[max];  
      }  
      public void appendBook(Book book){  
           this.books[last]=book;  
           last++;  
      }  
      public Book getBookAt(int index){  
           return books[index];  
      }  
      public int getLength(){  
           return last;  
      }  
 //     @Override  
 //     public Iterator iterator() {  
 //          // TODO Auto-generated method stub  
 //          return new BookShelfFrontIterator(this);  
 //     }  
      public Iterator iterator() {  
           // TODO Auto-generated method stub  
           return new BookShelfBackIterator(this);  
      }  
 }  
*주석된 부분만 바꾸면 반복자를 수정할 수 있다. 다른 클래스는 수정할 필요 없다.



- ConcreteIterator(구체적인 반복자)


1. BookShelfBackIterator


 package Sample;  
 import basic.pattern.Iterator;  
 public class BookShelfBackIterator implemeats Iterator {  
      private BookShelfArrange bookShelf;  
      private int index;  
      public BookShelfBackIterator(BookShelfArrange shelf) {  
           this.bookShelf = shelf;  
           index=0;  
      }  
      @Override  
      public Object next() {  
           Book book=bookShelf.getBookAt(index);  
           index++;  
           return book;  
      }  
      @Override  
      public boolean hasNext() {  
           if(index<bookShelf.getLength())  
                return true;  
           else  
                return false;  
      }  
 }  

2.BookShelfFrontIterator


 package Sample;  
 import basic.pattern.Iterator;  
 public class BookShelfFrontIterator implements Iterator {  
      private BookShelfArrange bookShelf;  
      private int index;  
      public BookShelfFrontIterator(BookShelfArrange shelf) {  
           this.bookShelf = shelf;  
           index=shelf.getLength()-1;  
      }  
      @Override  
      public Object next() {  
           Book book=bookShelf.getBookAt(index);  
           index--;  
           return book;  
      }  
      @Override  
      public boolean hasNext() {  
           if(index>-1)  
                return true;  
           else  
                return false;  
      }  
 }  


@ 실행


- Main


 package Sample;  
 import basic.pattern.Iterator;  
 public class Main {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           BookShelfArrange bookShelf=new BookShelfArrange(5);  
           bookShelf.appendBook(new Book("A"));  
           bookShelf.appendBook(new Book("B"));  
           bookShelf.appendBook(new Book("C"));  
           bookShelf.appendBook(new Book("D"));  
           bookShelf.appendBook(new Book("E"));  
           Iterator it=bookShelf.iterator();  
           while(it.hasNext()){  
                System.out.println(((Book)it.next()).getName());  
           }  
           System.out.println("End");  
      }  
 }  









2012년 4월 20일 금요일

[Java Design Pattern_1]Iterator 설명

# Iterator - 순서대로 지정해서 처리하기

@ Iterator 패턴이란, 무엇인가 많이 모여있는 것들을 순서대로 지정하면서 전체를 검색하는 처리를 실행하기 위한 것입니다.


@예제


 - Aggregate(집합체) : 집합체를 나타내는 인터페이스
    => 선언되어 있는 메소드는 iterator 메소드 하나뿐 집합체에 대응하는 Iterator를 1개 작성하기 위한 것입니다. 집합체를 하나씩 나열하고, 검색하고, 조사하고 싶을 때에는 iterator 메소드를 사용해서 Iterator 인터페이스를 구현한 클래스의 인스턴스를 1개 만듭니다.


- BookShelf(구체적인 집합체) : 서가를 나타내는 클래스
  => Aggregate 인터페이스로 구현(책 객체 집합을 가진 집합체)



 - Iterator(반복자) : 하나씩 나열하면서 검색을 실행하는 인터페이스
   => 다음 요소가 존재하는지, 다음요소를 가져오는 메서드

 - BookShelfIterator(구체적인 반복자) : 서가를 검색하는 클래스
  => Iterator 인터페이스를 구현하는 클래스 , 생성자에서 검색할 객체를 등록하고, 인덱스를 0으로 만든다.


 - Book : 책을 나타내는 클래스


 - Main : 동작 테스트용 클래스


@Why ?
  - 구현에 상관없이 Iterator를 사용할 수 있다.


 while (it.haSNext ()) {   
   Book book (Book) it.next () ;   
   System.out. println(book.getName()) ;   
 }  

 위의 코드의 while 루프는 BookShelf의 구현에는 의존하지 않습니다. BookShelf가 Vector 나 ArrayList나 상관없이 올바른 Iterator를 반환하면 루프는 전혀 변경하지 않아도 동작합니다.

- 디자인 패턴은 클래스의 재 이용화를 촉진합니다. 재이용화를 촉진한다는 것은 클래스를 부품처럼 사용할 수 있게 하고, 하나의 부품을 수정해도 다른 부품에는 큰 영향 없이 적은 수정만으로 끝낼 수 있다는 것을 의미합니다.

- 추상 클래스 ? 인터페이스 ? : 구체적인 클래스만 사용하면 클래스 간의 결합이 강해져서, 부품으로 재 이용하는 일이 어렵습니다. 결합을 약하게 해서 부품으로 재이용하기 쉽도록 하기 위해 추상 클래스나 인터페이스가 도입니다.

- 복수의 Iterator  : 하나씩 나열하는 구조가 Aggregate 역할의 외부에 놓여있다.라는 것은 Iterator 패턴의 특징 중 하나입니다. 이 특징으로 인해 하나의 ConcreteAggregate 역할에 대해서 복수의 ConcreteIterator 역할을 만들 수 있습니다.

- Iterator의 다양한 종류 : 뒤에서 시작해서 역방향으로 진행한다. // 정방향으로도, 역방향으로도 진행한다. 번호를 지정해서 갑자기 그곳으로 점프한다.