Java 디자인 모드 프로그래밍에서의 상태 모드와 정책 모드 비교

자바 응용 프로그램에서 상태 모델과 정책 모델을 정확하게 사용할 수 있도록 개발자는 이 두 모델 간의 차이를 명확하게 알아야 한다.비록 상태 모델과 전략 모델의 구조가 매우 비슷하지만 그들은 개폐 원칙을 따르고 모두 SOLID 설계 원칙의'O'를 대표하지만 그들의 의도는 완전히 다르다.Java의 정책 모드는 하나의 관련 알고리즘을 봉인하여 호출자에게 실행할 때의 유연성을 제공한다.호출자는 정책을 사용하는 Context 클래스를 수정하지 않고 실행할 때 다른 알고리즘을 선택할 수 있습니다.전략 모델을 사용하는 대표적인 예는 암호화 알고리즘, 압축 알고리즘, 정렬 알고리즘을 실현하는 것을 포함한다.다른 한편, 상태 모드는 하나의 대상을 사용하여 서로 다른 상태에서 서로 다른 행동을 나타낼 수 있다.실제 세계의 대상도 상태가 있고 상태에 따라 다른 표현을 할 수 있다. 예를 들어 자판기는hasCoin 상태에서만 물건을 팔 수 있다. 만약에 동전을 넣지 않으면 판매하지 않는다.이제 전략 모델과 상태 모델의 차이를 똑똑히 볼 수 있다. 그들의 목적은 다르다.상태 모드는 대상이 상태를 관리하는 데 도움을 줄 수 있고, 정책 모드는 클라이언트가 서로 다른 행동을 선택할 수 있도록 한다.또 하나 쉽게 볼 수 없는 차이점은 누가 행동의 변화를 구동하는가이다.정책 모드에서는 클라이언트가 구동하고 상하문 정보에 서로 다른 정책을 제공하며 상태 모드에서는 상태의 이동은Context나State 대상이 스스로 관리한다.마찬가지로, 만약 당신이 State 대상에서 상태를 수정한다면, 그것은 반드시 Context의 인용을 가지고 있어야 한다. 즉, 자동판매기에서 현재 Context의 상태를 수정하기 위해setState 방법을 사용할 수 있다는 것이다.다른 한편, 정책 대상은 Context의 인용을 가지고 있지 않으며, 클라이언트는 선택한 정책을 Context에 전달합니다.전략 모델과 상태 모델은 가장 쉽게 볼 수 있는 자바 디자인 모델에 대한 면접 문제이다. 이 자바 디자인 모델에 관한 글에서 우리는 이 점을 상세하게 소개할 것이다.우리는 이 두 모델의 공통점과 차이점을 탐색할 것이다. 이것은 당신이 이 두 모델에 대한 이해를 높이는 데 도움이 된다.
상태 모드와 정책 모드의 유사점:
정책 모드와 상태 모드의 UML 그림을 보면 매우 비슷해 보입니다.상태 모드에서 State 대상을 사용하여 행동을 바꾸는 대상을 Context 대상이라고 하는데, 유사한 정책 모드에서 Strategy 대상을 사용하여 행동을 바꾸는 대상도 Context 대상이다.클라이언트는 Context 대상과 상호작용한다는 것을 명심하세요.상태 모드에서 Context는 상태 대상의 방법 호출을 에이전트합니다. Context의 현재 대상은 구체적인 상태 대상입니다. 정책 모드에서 Context가 조작하는 것도 정책 대상입니다. 이 대상은 매개 변수로 들어오거나 Context 대상을 만들 때 제공됩니다.
이 두 가지 핵심 Java 디자인 모델의 유사점을 살펴보겠습니다.
상태 모드와 정책 모드는 Context 대상을 사용하는 데 영향을 주지 않고 새로운 상태나 정책을 추가하기 쉽다
두 가지 모델 모두 개폐의 디자인 원칙을 따른다. 즉, 당신의 디자인은 확장 개방에 대한 것이고 수정에 대한 폐쇄에 대한 것이다.이 두 가지 모델에서 Context는 수정에 대해 폐쇄적이다. 상태나 정책을 추가한다. 다른 상태의 Context 대상을 수정할 필요가 없거나 아주 작은 변경만 하면 된다.
상태 모드에서 Context 대상에 초기 상태가 있는 것처럼 정책 모드의 Context에도 기본 정책이 있습니다.
상태 모드는 서로 다른 상태 대상의 방식으로 서로 다른 행위를 봉하고, 정책 모드는 서로 다른 정책 대상으로 서로 다른 행위를 봉한다.
이 두 가지 모델은 모두 구체적인 자류에 의존하여 구체적인 행위를 실현한다.모든 구체적인 전략은 하나의 추상적인 전략 클래스에서 확장되고 모든 상태는 상태를 나타내는 인터페이스나 추상적인 클래스의 하위 클래스로도 사용된다.
상태 모드 인스턴스

public class WindowState { 
  private String stateValue; 
   
  public WindowState(String stateValue) { 
    this.stateValue = stateValue; 
  } 
   
  public String getStateValue() { 
    return stateValue; 
  } 
 
  public void setStateValue(String stateValue) { 
    this.stateValue = stateValue; 
  } 
   
  public void handle() { 
    /* 
     *  ,   
     */ 
    if (" ".equals(stateValue)) { 
      switchWindow(); 
      this.stateValue = " "; 
    } else if (" ".equals(stateValue)) { 
      switchFullscreen(); 
      this.stateValue = " "; 
    } 
  } 
   
  private void switchWindow() { 
    System.out.println(" "); 
  } 
   
  private void switchFullscreen() { 
    System.out.println(" "); 
  } 
   
} 

/** 
 *   
 */ 
public class WindowContext { 
  private WindowState state; 
   
  public WindowContext(WindowState state) { 
    this.state = state; 
  } 
   
  public WindowState getState() { 
    return state; 
  } 
   
  public void setState(WindowState state) { 
    this.state = state; 
  } 
   
  public void switchState() { 
    this.state.handle(); 
  } 
} 


/* 
 *  (State)    
 *  ,  
 *  ,  
 */ 
public class Test { 
  public static void main(String[] args) { 
    /* 
     *    ,  
     *  ,  
     */ 
    WindowContext context = new WindowContext(new WindowState(" ")); 
    context.switchState(); 
    context.switchState(); 
    context.switchState(); 
    context.switchState(); 
 
  } 
} 
인쇄

  
  
  
  

정책 모드 인스턴스

/** 
 *   
 *  :  
 */ 
public interface ICashSuper { 
   double acceptCash(double money); 
} 

/** 
 *   
 * @author stone 
 * 
 */ 
public class CashNormal implements ICashSuper { 
 
  @Override 
  public double acceptCash(double money) { 
    return money; 
  } 
 
} 


/** 
 *   
 * @author stone 
 * 
 */ 
public class CashRebate implements ICashSuper { 
  private double rebate; //  
  public CashRebate (double rebate) { 
    this.rebate = rebate; 
  } 
 
  @Override 
  public double acceptCash(double money) { 
    return new BigDecimal(money * rebate / 10).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); 
  } 
   
   
} 

/** 
 *     
 * @author stone 
 * 
 */ 
public class CashReturn implements ICashSuper { 
  private double moneyCondition; //  
  private double returnMoney; //  
  public CashReturn(double moneyCondition, double returnMoney) { 
    this.moneyCondition = moneyCondition; 
    this.returnMoney = returnMoney; 
  } 
 
  @Override 
  public double acceptCash(double money) {//  
    if (money >= moneyCondition) { 
      return money - Math.floor(money / moneyCondition) * returnMoney; 
    } else { 
      return money; 
    } 
  } 
   
   
} 


/** 
 *  ,  
 */ 
public class CashContext { 
  private ICashSuper casher; 
   
  public CashContext() { 
     
  } 
   
  public CashContext(ICashSuper casher) { 
    this.casher = casher; 
  } 
   
  public void setCasher(ICashSuper casher) { 
    this.casher = casher; 
  } 
   
  // ,  
  public double acceptCash(double money) { 
    return this.casher.acceptCash(money); 
  } 
   
} 


public class Test { 
  public static void main(String[] args) { 
    double money = 998; //  
    CashContext cashContext = new CashContext(new CashNormal()); 
    System.out.println(" :" + cashContext.acceptCash(money)); //    
     
    cashContext.setCasher(new CashRebate(8.5)); 
    System.out.println(" 85 :" + cashContext.acceptCash(money)); //      85  
     
    cashContext.setCasher(new CashReturn(300, 50)); 
    System.out.println(" 300  50:" + cashContext.acceptCash(money)); //      300  50 
     
  } 
} 

인쇄

 :998.0 
 85 :848.3 
 300  50:848.0 

정책 모드와 상태 모드의 차이
우리는 이미 이 두 모델이 구조적으로 매우 비슷하다는 것을 알았지만, 그것들은 여전히 다른 점이 있다.다음은 그들 사이의 관건적인 차이점을 살펴보자.
  • 정책 모델은 일련의 관련 알고리즘을 봉인했다. 클라이언트를 사용하면 실행할 때 조합과 의뢰를 통해 서로 다른 행위를 사용할 수 있고 상태 모델은 대상이 서로 다른 상태에서 서로 다른 행위를 보여줄 수 있다
  • 이 두 모델의 또 다른 차이점은 상태 모델이 대상의 상태를 봉인하고 전략 모델이 봉인하는 것은 하나의 알고리즘이나 전략이다.상태는 대상과 결합되어 있기 때문에 다시 사용할 수 없으며, 정책이나 알고리즘을 통해 상하문에 독립되어 중복 사용할 수 있다..
  • 상태 모드에서 상태 자체는 Context의 인용을 포함하여 상태 이동을 실현하지만 정책 모드는 Context의 인용이 없다
  • 구체적인 전략은 하나의 매개 변수로 그것들을 사용하는 대상에 전달할 수 있다. 예를 들어 Collections.comparator를 받아들이는 것은 전략입니다.다른 상태 자체는 Context 대상의 일부입니다. 시간이 지날수록 Context 대상은 한 상태에서 다른 상태로 이동합니다..
  • 비록 두 가지 모델이 모두 개폐 원칙을 따랐지만 전략 모델은 단일 직책 원칙을 따랐다. 왜냐하면 모든 전략은 독립된 알고리즘이고 서로 다른 전략은 다른 전략에 독립하기 때문이다.하나의 전략을 바꾸는 것은 다른 전략의 실현에 영향을 주지 않는다
  • 이론적으로 말하자면 전략 모델과 상태 모델은 또 하나 다르다. 전자가 정의한 것은 하나의 대상이'어떻게'한 가지 일을 하는 것이다. 예를 들어 데이터에 대해 어떻게 정렬하는가이다. 다른 한편, 상태 모델이 정의한 것은'무엇'과'언제'이다. 예를 들어 하나의 대상이 무엇을 할 수 있는지, 어느 시점에 어떤 상태에 있는지이다.
  • 상태의 이동 순서는 상태 모델에서 정의된 것이고 정책 모델에는 이런 요구가 없다.클라이언트는 어떤 정책을 사용하는지 마음대로 선택할 수 있습니다.
  • 흔히 볼 수 있는 전략 모델의 예는 모두 봉인 알고리즘이다. 예를 들어 정렬 알고리즘, 암호화 알고리즘, 또는 압축 알고리즘이다.코드에 서로 다른 알고리즘을 사용해야 한다는 것을 발견하면 전략 모드를 고려할 수 있다.만약 당신이 상태를 관리하고 상태 간의 이동을 해야 하며, 많은 조건 문장을 끼워 넣기를 원하지 않는다면, 상태 모델은 당신의 첫 번째 선택이다. 왜냐하면 그것은 매우 간단하기 때문이다
  • 마지막으로 가장 중요한 차이점은 전략 모델은 클라이언트가 처리하고 상태의 변화는 Context나 State 대상이 모두 진행할 수 있다는 것이다
  • 이것이 바로 Java의 정책 모드와 상태 모드에 대한 모든 차이점입니다.내가 말한 바와 같이 그들은 UML 그림에서 매우 유사하게 보인다. 둘 다 개폐 원칙을 따르고 행위를 봉인했다.정책 모드는 알고리즘이나 정책을 봉인하는 데 사용되며, 실행할 때 매개 변수나 조합 대상으로 Context 대상에 제공되고, 상태 모드는 상태 이동을 관리하는 데 사용된다.

    좋은 웹페이지 즐겨찾기