디자인 패턴

강력한 객체 지향(OO) 주제에 대한 좋은 지식을 갖고 있다는 것은 분명히 큰 강점이지만 OO 디자인 패턴에 대한 적절한 개념 없이 이러한 개념을 아는 것을 고려하면 실제 응용 프로그램에서 작업할 때 몇 가지 재앙적인 장애물이 생길 수 있습니다.

여기서는 코드를 보다 유연하고 재사용 가능하며 효율적으로 만드는 데 도움이 되는 몇 가지 알려진 편리한 디자인 패턴에 대한 용어집을 만들었습니다. 도움이 되길 바랍니다!

Patterns aren’t invented, they are discovered




전제 조건



1. 캡슐화(Encapsulation) : 클래스의 데이터 멤버와 데이터 메소드를 사용자 정의 클래스 내부에 결합하는 객체지향적 절차.

2. 추상화(Abstraction) : 특정 세부 사항을 숨기고 사용자에게 꼭 필요한 정보만 보여주는 과정. 추상 클래스 또는 인터페이스를 사용하여 달성됩니다.

3. 다형성(Polymorphism): 객체가 다양한 형태를 취할 수 있는 능력. 이는 동일한 작업을 다른 방식으로 수행하는 데 도움이 됩니다.

4. 상속: 하나의 개체가 부모 개체의 모든 속성과 동작을 획득하는 메커니즘입니다.


행동 패턴



1. 전략 패턴
알고리즘 계열을 정의하고, 각각을 캡슐화하고, 상호 교환 가능하게 만듭니다. 전략을 사용하면 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있습니다.

구현
몇 가지 작업을 동적으로 수행해야 하는 Demo 클래스가 있다고 가정해 보겠습니다. 우리는 Add(), Subtract() 및 Multiply()와 같은 다양한 작업 클래스에 의해 구현된 전략 인터페이스를 사용하는 Rundemo 클래스를 만듭니다.

Step 1
Creating the interface:Strategy.java

public interface Strategy {
   public int operation(int num1, int num2);
}

------------------------------------------------------------------
Step 2
Create concrete classes implementing the same interface: OperationAdd.java

public class Add implements Strategy{
   @Override
   public int operation(int num1, int num2) {
      return num1 + num2;
   }
}

------------------------------------------------------------------
OperationSubstract.java

public class Subtract implements Strategy{
   @Override
   public int operation(int num1, int num2) {
      return num1 - num2;
   }
}

------------------------------------------------------------------
OperationMultiply.java

public class Multiply implements Strategy{
   @Override
   public int operation(int num1, int num2) {
      return num1 * num2;
   }
}

------------------------------------------------------------------
Step 3
Create Rundemo Class: Rundemo.java

public class Rundemo {
   private Strategy strategy;

   public Rundemo(Strategy strategy){
      this.strategy = strategy;
   }

   public int executeStrategy(int num1, int num2){
      return strategy.operation(num1, num2);
   }
}

------------------------------------------------------------------
Step 4
Use the Rundemo to see change in behavior when it changes its Strategy: Demo.java

public class Demo {
   public static void main(String[] args) {
      Rundemo rundemo = new Rundemo(new Add());     
      System.out.println("8 + 5 = " + context.executeStrategy(8, 5));

      rundemo = new Rundemo(new Substract());       
      System.out.println("8 - 5 = " + context.executeStrategy(8, 5));

      rundemo = new Rundemo(new Multiply());        
      System.out.println("8 * 5 = " + context.executeStrategy(8, 5));
   }
}

------------------------------------------------------------------
Step 5
Verify the output.

8 + 5 = 13
8 - 5 = 3
8 * 5 = 40


기억해야 할 핵심 사항
  • 상속보다 구성을 선호합니다.
  • 다양한 항목을 캡슐화합니다.
  • 이전에 HAS-A, IS-A 관계에 대한 명확한 그림이 있어야 합니다.
    구현합니다.
  • 구현이 아닌 인터페이스로 프로그래밍합니다.



  • 2. 관찰자 패턴
    개체 간의 일대다 종속성을 정의하여 한 개체의 상태가 변경되면 모든 종속 개체에 알림이 자동으로 전송되고 업데이트됩니다. 하나의 소스에서 동적으로 처리되는 여러 옵저버의 업데이트, 삭제 및 등록과 관련된 사용 사례는 종종 이 패턴을 활용합니다.

    구현
    Subject 의 도움으로 다수의 옵저버에 대해 동적으로 몇 가지 작업(예: 주제 상태 업데이트)을 수행해야 하는 시스템인 Demo 클래스가 있다고 가정해 보겠습니다. 추상 클래스 Observer와 Observer 클래스를 확장하는 구체적인 클래스 Subject를 만들었습니다. Demo 클래스는 실제 관찰자 패턴을 보여주기 위해 주제 클래스 구체적인 클래스 객체를 사용합니다.

    Step 1
    Create Subject class : Subject.java
    
    import java.util.ArrayList;
    import java.util.List;
    public class Subject {
    
       private List<Observer> observers = new ArrayList<Observer>();
       private int state;
    
       public int getState() {
          return state;
       }
    
       public void setState(int state) {
          this.state = state;
          notifyAllObservers();
       }
    
       public void attach(Observer observer){
          observers.add(observer);      
       }
    
       public void notifyAllObservers(){
          for (Observer observer : observers) {
             observer.update();
          }
       }    
    }
    
    ------------------------------------------------------------------
    Step 2
    Create Observer class : Observer.java
    
    public abstract class Observer {
       protected Subject subject;
       public abstract void update();
    }
    
    ------------------------------------------------------------------
    Step 3
    Create concrete observer classes : BinaryStateStringObserver.java
    
    public class BinaryStateStringObserver extends Observer{
    
       public BinaryStateStringObserver(Subject subject){
          this.subject = subject;
          this.subject.attach(this);
       }
    
       @Override
       public void update() {
          System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); 
       }
    }
    
    ------------------------------------------------------------------
    OctalStringStateObserver.java
    
    public class OctalStringStateObserver extends Observer{
    
       public OctalStringStateObserver(Subject subject){
          this.subject = subject;
          this.subject.attach(this);
       }
    
       @Override
       public void update() {
         System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); 
       }
    }
    
    ------------------------------------------------------------------
    HexaStateStringObserver.java
    
    public class HexaStateStringObserver extends Observer{
    
       public HexaStateStringObserver(Subject subject){
          this.subject = subject;
          this.subject.attach(this);
       }
    
       @Override
       public void update() {
          System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); 
       }
    }
    
    ------------------------------------------------------------------
    Step 4
    Use Subject and concrete observer objects : Demo.java
    
    public class Demo {
       public static void main(String[] args) {
          Subject subject = new Subject();
    
          new HexaStateStringObserver(subject);
          new OctalStateStringObserver(subject);
          new BinaryStateStringObserver(subject);
    
          System.out.println("First state change: 10"); 
          subject.setState(10);
          System.out.println("Second state change: 12");    
          subject.setState(12);
       }
    }
    
    ------------------------------------------------------------------
    Step 5
    Verify the output.
    
    First state change: 10
    Hex String: A
    Octal String: 12
    Binary String: 1010
    Second state change: 12
    Hex String: C
    Octal String: 14
    Binary String: 1100
    


    기억해야 할 핵심 사항
  • 개체 간에 느슨하게 결합된 디자인을 위해 노력합니다.
    상호 작용
  • 대상이 공통 인터페이스를 사용하여 관찰자를 업데이트합니다
  • .
  • 대상이 아무것도 모른다는 점에서 관찰자가 느슨하게 결합됨
    옵저버를 구현한다는 점 외에는
    상호 작용.

  • 계속하려면 ...

    좋은 웹페이지 즐겨찾기