// 패턴 적용

// 2. 변하는 것을 '클래스화' 하자.

// -- Strategy pattern (전략패턴)

// 2.1 인터페이스를 설계하자.


  1. interface IValidator {
  2.         boolean validate(char c);
  3. }
  4. class DigitOnlyValidator implements IValidator {
  5.  
  6.         @Override
  7.         public boolean validate(char c) {
  8.                 return Character.isDigit(c);
  9.         }
  10. }
  11. class AllPassValidator implements IValidator {
  12.  
  13.         @Override
  14.         public boolean validate(char c) {
  15.                 return true;
  16.         }
  17.        
  18. }
  19. class LineEdit2 {
  20.         private JFrame frame;
  21.         private StringBuilder builder = new StringBuilder();
  22.         private IValidator iValidator;
  23.        
  24.         public void setValidator(IValidator iv) {
  25.                 iValidator = iv;
  26.         }
  27.         public LineEdit2() {
  28.                 frame = new JFrame();
  29.                 frame.setSize(300200);
  30.                 frame.setTitle("EditBox");
  31.                 iValidator = new AllPassValidator(); //default
  32.                
  33.                 Container cp = frame.getContentPane();
  34.                 cp.setLayout(new FlowLayout());
  35.                
  36.                 final JLabel label = new JLabel("");
  37.                 cp.add(label);
  38.                
  39.                 frame.addKeyListener(new KeyListener() { //inner class
  40.                        
  41.                         @Override
  42.                         public void keyTyped(KeyEvent e) { //키를 입력했다. (Press + Release)
  43.                                 char c = e.getKeyChar();
  44.                                 System.out.println(c);
  45.                                 if(== '\n') {
  46.                                         builder = new StringBuilder();
  47.                                         label.setText("");
  48.                                 }
  49.                                 if(iValidator.validate(c)) {
  50.                                         builder.append(c);
  51.                                         label.setText(builder.toString());
  52.                                 }
  53.                         }
  54.                         @Override
  55.                         public void keyReleased(KeyEvent e) {} // 키를 뗐다.
  56.                         @Override
  57.                         public void keyPressed(KeyEvent e) {} // 키를 눌렀다.
  58.                 });
  59.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 프로세스 종료시
  60.                
  61.         }
  62.         public boolean validate(char c) {
  63.                 return Character.isDigit(c);
  64.         }
  65.  
  66.         public void show() {
  67.                 frame.setVisible(true);
  68.  
  69.         }
  70. }
  71. public class Ex2 {
  72.        
  73.         public static void main(String...args) {       
  74.                 LineEdit2 lineEdit2 = new LineEdit2();
  75.                 lineEdit2.setValidator(new DigitOnlyValidator());
  76.                 lineEdit2.show();
  77.         }
  78. }


'java > design_pattern' 카테고리의 다른 글

Decorator Pattern  (0) 2014.06.27
Composite Pattern  (0) 2014.06.27
Template Method Pattern  (0) 2014.06.27
Adapter 패턴  (0) 2014.06.27
Java Singleton 선언하는법  (0) 2014.06.18

// Template Method Pattern

// - 변하지 않는 공통의 알고리즘은 부모가 public 으로 제공하고

// - 변하지 않은 코드 내부의 변해야 하는 정책만 자식이 재정의 하도록 하자.


  1. // 추상클래스 기반의 약한 결합
  2. abstract class Shape {
  3.         public final void draw() { //재정의 금지 final
  4.                 drawImpl();
  5.         }
  6.         protected abstract void drawImpl();
  7.         protected abstract Shape clone();
  8.        
  9. }
  10. class Rect extends Shape {
  11.         @Override
  12.         public void drawImpl() {
  13.                 System.out.println("Draw Rect.");
  14.         }
  15.         public Rect clone() {
  16.                 return new Rect();
  17.         }
  18.        
  19. }
  20. class Circle extends Shape {
  21.         @Override
  22.         public void drawImpl() {
  23.                 System.out.println("Draw Circle.");
  24.         }
  25.         @Override
  26.         public Circle clone() {
  27.                 return new Circle();
  28.         }
  29.        
  30. }
  31. public class Ex1 {
  32.         private static Scanner scan;
  33.  
  34.         public static void main(String...args) {
  35.                 List<Shape> list = new ArrayList<>();
  36.                 // 강한결합 : 하나의 클래스가 다른 클래스를 사용 할 때 클래스의 이름을 바로 사용
  37.                 // - 교체 불가능한 경직된 디자인
  38.                
  39.                 scan = new Scanner(System.in);
  40.                 while (true) {
  41.                         System.out.println("Choice : ");
  42.                         int cmd = scan.nextInt();
  43.                         if(cmd == 0) {
  44.                                 break;
  45.                         }
  46.                         switch (cmd) {
  47.                         case 1:
  48.                                 list.add(new Rect());
  49.                                 break;
  50.                         case 2:
  51.                                 list.add(new Circle());
  52.                                 break;
  53.                         case 8:
  54.                                 System.out.println("copy : ");
  55.                                 int idx = scan.nextInt();
  56.                                 list.add(list.get(idx).clone());
  57.                                 break;
  58. //                              switch(list.get(idx).type) {
  59. //                              case 1:
  60. //                                      list.add(new Rect());
  61. //                                      break;
  62. //                              case 2:
  63. //                                      list.add(new Circle());
  64. //                                      break;
  65. //                              }
  66.                                
  67.                         case 9:
  68.                                 for(Shape s : list) {
  69.                                         s.draw();
  70.                                 }
  71.                                 break;
  72.                         }
  73.                 }
  74.         }
  75. }


'java > design_pattern' 카테고리의 다른 글

Composite Pattern  (0) 2014.06.27
Strategy Pattern  (0) 2014.06.27
Adapter 패턴  (0) 2014.06.27
Java Singleton 선언하는법  (0) 2014.06.18
Design Pattern 기본 원칙  (0) 2014.06.18

// 기존 클래스의 인터페이스를 변경하여 클라이언트가 요구하는 새로운 클래스를 만드는 디자인 기법

// 라이브러리를 설계할 때 사용자가 쉽게 사용할 수 있게하고, 잘못된 사용은 어렵게 해라.

// 포함 > 상속

// - 쉽게 내부구현를 바꿀 수 있다. 

// -- 사용자는 성능향상만을 느낄 수 있다.

// - 외부로 노출되는 인터페이스 API를 제어가능하다.

// -- 일반적으로 상속 이용 시 부모의 public 인터페이스를 노출해야하지만 포함은 쉽게 제어 가능하다.

// -- 잘못된 사용을 할 확률이 낮아진다.


  1. /**
  2.  * Vector class를 상속을 기반으로 한 설계
  3.  * 단점 - Vector의 인터페이스가 노출되어 의도치 않은 동작을 할 수 있다.
  4.  * @author YM,Jung
  5.  *
  6.  * @param <E>
  7.  */
  8. class Stack<E> extends Vector<E> {
  9.         // java 1.0 까지의 Stack은 이런방식으로 구현되어 있다.
  10.         // 상속을 통한 재사용을 지양하자. 컴포지션(포함)으로 사용하자.
  11.         private static final long serialVersionUID = -7937875509563141466L;
  12.  
  13.         public Stack() {
  14.         }
  15.  
  16.         public boolean empty() {
  17.                 return isEmpty();
  18.         }
  19.  
  20.         public E push(E object) {
  21.                 addElement(object);
  22.                 return object;
  23.         }
  24.  
  25.         @SuppressWarnings("unchecked")
  26.         public E pop() {
  27.                 if (elementCount == 0) {
  28.                         throw new EmptyStackException();
  29.                 }
  30.                 final int index = --elementCount;
  31.                 final E obj = (E) elementData[index];
  32.                 elementData[index] = null; // GC대상이 될 수 있게 null을 대입. 메모리 릭을 예방
  33.                 return obj;
  34.         }
  35. }
  36.  
  37. /**
  38.  * 포함을 기반으로 한 설계
  39.  *
  40.  * @author YM,Jung
  41.  *
  42.  * @param <E>
  43.  */
  44. class Stack2<E> {
  45.         private List<E> data = new ArrayList<>();
  46.        
  47.         public Stack2() {}
  48.         public E push(E obj) {
  49.                 data.add(obj);
  50.                 return obj;
  51.         }
  52.         public E pop() {
  53.                 if(data.size() == 0) {
  54.                         throw new EmptyStackException();
  55.                 }
  56.                 final int index = data.size() - 1;
  57.                 final E obj = data.get(index);
  58.                
  59.                 data.remove(index);
  60.                 return obj;
  61.         }
  62.         public boolean empty() {
  63.                 return data.isEmpty();
  64.         }
  65. }
  66. public class Ex1 {
  67.  
  68.         public static void main(String[] args) {
  69.                 Stack2<String> s = new Stack2<>();
  70.                 s.push("111");
  71.                 s.push("222");
  72.                 s.push("333");
  73.                 s.push("444");
  74.                 s.push("555");
  75.                
  76.                 while(!s.empty()) {
  77.                         System.out.println(s.pop());
  78.                 }
  79.         }
  80. }


'java > design_pattern' 카테고리의 다른 글

Strategy Pattern  (0) 2014.06.27
Template Method Pattern  (0) 2014.06.27
Java Singleton 선언하는법  (0) 2014.06.18
Design Pattern 기본 원칙  (0) 2014.06.18
Builder Pattern  (0) 2014.06.17

Singleton Pattern

 - 유일한 시스템 컴 포넌트를 선언

1. 드래코니언 동기화 

 - 성능적으로 이슈

 - 멀티쓰레드 이슈

2. 더블 락킹 (Double Locking)

 - 성능적으로 이슈 (1.5이하에서 사용)

3. Singleton Holder

 - 1.5 이상. 

4. 한정적 메모리의 Singleton - WeakReference

 - VM이 한정적일때 사용

 - 가비지 콜렉터의 대상이 됨.

5. Enum을 이용한 생성 (가장 추천)

  1. enum Singleton {
  2.         // Thread Safe 하다. 하나만 있음을 보장한다.
  3.         // Serialization 에서도 안전하다.
  4.         // Reflection 에 대해서도 보장한다.
  5.         // - Effective Java 에 소개.
  6.         // - 유럽에서 사용한다.
  7.         // - 많이 알려지지 않았지만 Java언어에서 보장하는 좋은 방법
  8.         INSTANCE;
  9.        
  10.         public Singleton getInstance() {
  11.                 return INSTANCE;
  12.         }
  13. }


  1. // Singleton
  2. // 유일한 시스템 컴포넌트를 설계할 때 사용.
  3. class CursorOld {
  4.         // DCL.
  5.         private static volatile CursorOld INSTANCE = null; // 두개이상 존재 가능성이 있으므로 volatile 선언
  6.  
  7.         private CursorOld() {
  8.  
  9.         }
  10.  
  11.         // public static Cursor getInstance() {
  12.         // 1. Draconian 동기화 // 성능적으로 이슈가 있다.
  13.         // public static synchronized Cursor getInstance() {
  14.         // 2. Double checked locking
  15.         // 성능적으로 떨어짐 (1.5 이하)
  16.         public static CursorOld getInstance() {
  17.                 if (INSTANCE == null) {
  18.                         // 멀티쓰레드 안정성이 없다.
  19.                         synchronized (CursorOld.class) { //성능 이슈를 발생
  20.                                 if (INSTANCE == null) {
  21.                                         INSTANCE = new CursorOld();
  22.                                 }
  23.                         }
  24.                 }
  25.                 return INSTANCE;
  26.         }
  27. }
  28.  
  29. // 사용되지 않을 수도 있다. 시작부터 끝까지 존재한다.
  30. // lazy initialize 가 필요할 수도있다. 성능적으로 도움
  31.  
  32. // for jdk 1.5 이상.
  33. class Cursor {
  34.         // 만들면서 초기화.
  35.         public static final Cursor INSTANCE = new Cursor();
  36.  
  37.         // 1. public
  38.         private Cursor() {
  39.         }
  40.  
  41.         // 2. static factory method
  42.         public static Cursor getInstance() { // 메소드로 접근해도 느리지 않다.
  43.                 return INSTANCE;
  44.         }
  45. }
  46.  
  47. // Initialization On Demand Holder Idiom
  48. // lazy initialize.
  49. class SingletonHolder {
  50.         private SingletonHolder() {
  51.  
  52.         }
  53.  
  54.         private static class SingleHolder {
  55.                 private static final SingletonHolder INSTANCE = new SingletonHolder();
  56.         }
  57.  
  58.         // 내부적으로 인스턴스가 호출될때 처음 접근, 그때 생성을 보장
  59.         public static SingletonHolder getInstance() {
  60.                 return SingleHolder.INSTANCE;
  61.         }
  62. }
  63.  
  64. // weak reference를 통한 해제 가능한 Singleton
  65. // JavaVM이 한정된 메모리를 가지고 있을 때 유용하다.
  66. //메모리 부족시 지웠다가 없으면 다시 생성
  67. // for android
  68. class Singleton {
  69.         static private WeakReference<Singleton> singleton;
  70.        
  71.         public Singleton getInstance() {
  72.                 Singleton m = singleton.get();
  73.                 if(!= null) {
  74.                         return m;
  75.                 }
  76.                 synchronized (Singleton.class) {
  77.                         m = singleton.get();
  78.                         if(!= null) {
  79.                                 return m;
  80.                         }
  81.                         m = new Singleton();
  82.                         singleton = new WeakReference<Singleton>(m);
  83.                        
  84.                 }
  85.                 return m;
  86.         }
  87. }


'java > design_pattern' 카테고리의 다른 글

Template Method Pattern  (0) 2014.06.27
Adapter 패턴  (0) 2014.06.27
Design Pattern 기본 원칙  (0) 2014.06.18
Builder Pattern  (0) 2014.06.17
Java Beans Pattern  (0) 2014.06.17

OCP (Open-Close Principle)

수정에는 닫혀있음, 확장에는 열려있음

 - 인터페이스 기반으로 설계

SRP (Single Responsibility Principle)

단일책임의 법칙

 - 하나의 클래스가 하나 이상의 책임을 맡게되면 결합도가 커진다.

DIP (Dependency Inversion Principle)

의존관계 역전의 법칙

 - 구체클래스에 의존하지 말고 인터페이스에 의존

 -- ISP (Interface Segregation Principle)

 -- 인터페이스 분리의 법칙

LSP (Liskov's Substitution Principle)

리스코프의 치환 법칙

  -- 공통의 기능을 상속을 받아 필요한 기능은 치환

'java > design_pattern' 카테고리의 다른 글

Adapter 패턴  (0) 2014.06.27
Java Singleton 선언하는법  (0) 2014.06.18
Builder Pattern  (0) 2014.06.17
Java Beans Pattern  (0) 2014.06.17
Telescoping Pattern  (0) 2014.06.17

장점

 - 코드의 가독성이 높다.

 - 생성하는 객체를 불변객체로 만들기 쉽다.

단점

 - 빌더의 생성비용이 소모된다.

 


이클립스에는 빌더를 따로 추가해주는 자동 생성 툴은 없다. 코드 작성이 까다롭다.

생성자에 필수 값을 넣고 빌더에 Optional한 값을 넣자.


  1. class NutiritionFactsBuilder {
  2.         private final int servingSize;
  3.         private final int servings;
  4.  
  5.         // optional
  6.         private final int calories;
  7.         private final int fat;
  8.         private final int sodium;
  9.         private final int carbohydrate;
  10.  
  11.         private NutiritionFactsBuilder(Builder builder) {
  12.                 servingSize = builder.servingSize;
  13.                 servings = builder.servings;
  14.                 calories = builder.calories;
  15.                 fat = builder.fat;
  16.                 sodium = builder.sodium;
  17.                 carbohydrate = builder.carbohydrate;
  18.         }
  19.  
  20.         @Override
  21.         public String toString() {
  22.                 return "NutiritionFactsBuilder [servingSize=" + servingSize
  23.                                 + ", servings=" + servings + ", calories=" + calories
  24.                                 + ", fat=" + fat + ", sodium=" + sodium + ", carbohydrate="
  25.                                 + carbohydrate + "]";
  26.         }
  27.  
  28.         public static class Builder {
  29.                 private final int servingSize;
  30.                 private final int servings;
  31.  
  32.                 // optional
  33.                 private int calories = 0;
  34.                 private int fat = 0;
  35.                 private int sodium = 0;
  36.                 private int carbohydrate = 0;
  37.  
  38.                 public Builder(int servingSize, int servings) {
  39.                         this.servingSize = servingSize;
  40.                         this.servings = servings;
  41.                 }
  42.  
  43.                 public Builder calories(int value) {
  44.                         calories = value;
  45.                         return this; // 체이닝 기법을 사용하기 위함.
  46.                 }
  47.  
  48.                 public Builder fat(int value) {
  49.                         fat = value;
  50.                         return this;
  51.                 }
  52.  
  53.                 public Builder sodium(int value) {
  54.                         sodium = value;
  55.                         return this;
  56.                 }
  57.  
  58.                 public Builder carbohydrate(int value) {
  59.                         carbohydrate = value;
  60.                         return this;
  61.                 }
  62.  
  63.                 public NutiritionFactsBuilder build() {
  64.                         return new NutiritionFactsBuilder(this);
  65.                 }
  66.  
  67.         }
  68. }
  69.  
  70. public class Ex3 {
  71.         public static void main(String... args) {
  72.                 NutiritionFactsBuilder obj = new NutiritionFactsBuilder.Builder(100,
  73.                                 200).calories(10).carbohydrate(300).fat(10).build();
  74.                 System.out.println(obj.toString());
  75.         }
  76. }


'java > design_pattern' 카테고리의 다른 글

Java Singleton 선언하는법  (0) 2014.06.18
Design Pattern 기본 원칙  (0) 2014.06.18
Java Beans Pattern  (0) 2014.06.17
Telescoping Pattern  (0) 2014.06.17
프론트 컨트롤러 패턴  (0) 2013.05.07

장점

 - 명료하다.

 - 이해하기가 쉽다.

단점

 - 객체가 불완전한 상태로 생성될 수 있다.

 - 멀티쓰레드 사용 시 불완전한 객체의 이슈가 발생할 수 있다.

 

set들의 향연을 보다보면 실수가 생길법도 하다.

가급적 지양하자.


  1. class NutiritionFactsBeans {
  2.         private int servingSize;
  3.         private int servings;
  4.  
  5.         // optional
  6.         private int calories;
  7.         private int fat;
  8.         private int sodium;
  9.         private int carbohydrate;
  10.        
  11.         public void setServingSize(int servingSize) {
  12.                 this.servingSize = servingSize;
  13.         }
  14.         public void setServings(int servings) {
  15.                 this.servings = servings;
  16.         }
  17.         public void setCalories(int calories) {
  18.                 this.calories = calories;
  19.         }
  20.         public void setFat(int fat) {
  21.                 this.fat = fat;
  22.         }
  23.         public void setSodium(int sodium) {
  24.                 this.sodium = sodium;
  25.         }
  26.         public void setCarbohydrate(int carbohydrate) {
  27.                 this.carbohydrate = carbohydrate;
  28.         }
  29.         @Override
  30.         public String toString() {
  31.                 return "NutiritionFactsBeans [servingSize=" + servingSize
  32.                                 + ", servings=" + servings + ", calories=" + calories
  33.                                 + ", fat=" + fat + ", sodium=" + sodium + ", carbohydrate="
  34.                                 + carbohydrate + "]";
  35.         }
  36.        
  37. }
  38.  
  39. public class Ex2 {
  40.         public static void main(String... args) {
  41.                 NutiritionFactsBeans cola = new NutiritionFactsBeans();
  42.                 cola.setCalories(240);
  43.                 cola.setCarbohydrate(100);
  44.                 cola.setFat(10);
  45.                 cola.setServings(11);
  46.                 cola.setServingSize(99);
  47.                 cola.setSodium(20);
  48.                 System.out.println(cola.toString());
  49.         }
  50. }


'java > design_pattern' 카테고리의 다른 글

Design Pattern 기본 원칙  (0) 2014.06.18
Builder Pattern  (0) 2014.06.17
Telescoping Pattern  (0) 2014.06.17
프론트 컨트롤러 패턴  (0) 2013.05.07
디자인패턴 개인 메모.  (0) 2012.03.29
장점
 - 생성에 대한 일관성을 유지한다.
단점
 - 가독성이 좋지않다.
 - 런타임 오류가 발생할 수 있다. (에러잡기가 어렵다.)

생성자에 딸린 몇개씩 추가되는 인자들을 확인하자.
3~4개정도는 쉽게 만들 수 있지만
그 이상 시 순서와 채워넣는 인자를 잘못넣어 실수가 발생할 수 있다.
 
  1. class NutiritionFacts {
  2.         private final int servingSize;
  3.         private final int servings;
  4.  
  5.         // optional
  6.         private final int calories;
  7.         private final int fat;
  8.         private final int sodium;
  9.         private final int carbohydrate;
  10.  
  11.         public NutiritionFacts(int servingSize, int servings, int calories,
  12.                         int fat, int sodium, int carbohydrate) {
  13.                 this.servingSize = servingSize;
  14.                 this.servings = servings;
  15.                 this.calories = calories;
  16.                 this.fat = fat;
  17.                 this.sodium = sodium;
  18.                 this.carbohydrate = carbohydrate;
  19.         }
  20.  
  21.         public NutiritionFacts(int servingSize, int servings) {
  22.                 this(servingSize, servings, 0000);
  23.         }
  24.  
  25.         public NutiritionFacts(int servingSize, int servings, int calories) {
  26.                 this(servingSize, servings, calories, 000);
  27.         }
  28.  
  29.         public NutiritionFacts(int servingSize, int servings, int calories, int fat) {
  30.                 this(servingSize, servings, calories, fat, 00);
  31.         }
  32.  
  33.         public NutiritionFacts(int servingSize, int servings, int calories,
  34.                         int fat, int sodium) {
  35.                 this(servingSize, servings, calories, fat, sodium, 0);
  36.         }
  37.  
  38.         @Override
  39.         public String toString() {
  40.                 return "NutiritionFacts [servingSize=" + servingSize + ", servings="
  41.                                 + servings + ", calories=" + calories + ", fat=" + fat
  42.                                 + ", sodium=" + sodium + ", carbohydrate=" + carbohydrate + "]";
  43.         }
  44. }


'java > design_pattern' 카테고리의 다른 글

Design Pattern 기본 원칙  (0) 2014.06.18
Builder Pattern  (0) 2014.06.17
Java Beans Pattern  (0) 2014.06.17
프론트 컨트롤러 패턴  (0) 2013.05.07
디자인패턴 개인 메모.  (0) 2012.03.29

Front Controller Pattern.

몇 개의 서블릿이 중앙집중식으로 모든 요청을 다 받아서 처리하는 방식

대표적 - Spring.


초기에는 URL당 하나의 서블릿을 등록, 독립적 기능을 담당하게 함.

처리방식 - 서블릿 선행작업 수행, 요청의 기능을 담당하는 핸들러 클래스 호출


Spring에서는 최소한의 서블릿으로 처리 (프론트 컨트롤러 패턴 적용)

'java > design_pattern' 카테고리의 다른 글

Design Pattern 기본 원칙  (0) 2014.06.18
Builder Pattern  (0) 2014.06.17
Java Beans Pattern  (0) 2014.06.17
Telescoping Pattern  (0) 2014.06.17
디자인패턴 개인 메모.  (0) 2012.03.29

GoF 사용 패턴 종류.

Iterator - List의 항목을 찾아 처리

Chain of Reposibility - 값을 넘겨 처리

ex)반환값을 Handler에 넘김. 에러처리에 용이함.

Bridge - Interface와 Impl을 나누어 놓음. 선언과 구현을 분리해놓음으로 유연한 확장성

State - 클래스로 상태를 반환. 그에 따른 처리. 

'java > design_pattern' 카테고리의 다른 글

Design Pattern 기본 원칙  (0) 2014.06.18
Builder Pattern  (0) 2014.06.17
Java Beans Pattern  (0) 2014.06.17
Telescoping Pattern  (0) 2014.06.17
프론트 컨트롤러 패턴  (0) 2013.05.07

+ Recent posts