[디자인 패턴 시리즈 19] 상태 모드의 원리와 전략 모드 및 책임 체인 모드와의 차이점 분석

디자인 패턴 시리즈 목록

디자인 패턴 항공권
세 가지 공장 모델 탑승 입구
전략 모드 탑승 입구
위임 모드 탑승 입구
템플릿 방법 패턴 탑승 입구
관찰자 모드 탑승 입구
싱글 톤 모드 탑승 입구
프로토 타입 모드 탑승 입구
대행사 모델 탑승 입구
데코레이터 모드 탑승 입구
어댑터 모드 탑승 입구
빌더 모드 탑승 입구
책임 사슬 모델 탑승 입구
플라이급 모델 탑승 입구
조합 모드 탑승 입구
외관 패턴 탑승 입구
브리지 모드 탑승 입구
중개 모델 탑승 입구
반복자 모드 탑승 입구
상태 모드 탑승 입구
통역사 모드 탑승 입구
메모 모드 탑승 입구
명령 모드 탑승 입구
방문자 모드 탑승 입구
소프트웨어 디자인의 7 가지 원칙과 디자인 패턴 요약 탑승 입구

머리말

상태는 개발자에게 매우 친숙합니다. 정상적인 개발에서 객체의 상태는 항상 분리 할 수 ​​없습니다. 예를 들어, 검토 프로세스는 지속적인 상태 흐름의 프로세스이고 주문 프로세스는 지속적인 상태 흐름의 프로세스이자 상태 모드입니다. 우리의 상태 순환 프로세스에서 비즈니스 처리 논리를 더 잘 해결하는 것입니다.

상태 모드 란?

상태 머신 패턴이라고도하는 상태 패턴은 내부 상태가 변경되는 동안 개체가 동작을 변경하여 수정 된 클래스처럼 보이게합니다.

상태 패턴에서 클래스의 동작은 상태에 의해 결정되며 상태마다 동작이 다릅니다. 상태 패턴의 목적은 객체가 함께 동작을 변경하도록하는 것입니다.

상태 패턴의 핵심은 동작을 각 상태에 바인딩하는 것입니다.

좋습니다. 이제 다시 가장 할 시간입니다. 대화는 저렴합니다. 코드를 보여주세요 . 먼저 아주 간단한 예를 살펴 보겠습니다.

상태 패턴 예

아래에서는 주문 상태의 흐름을 기반으로 한 간단한 예를 작성합니다. 주문에 지불, 수신 및 수신 (완료)의 세 가지 상태 만 있다고 가정합니다.

1. 먼저 모든 상태의 모든 동작을 정의해야하는 추상 상태 클래스를 만듭니다.

package com.zwx.design.pattern.state;

public abstract class AbstractOrderState {
    
    
    protected OrderContext orderContext;

    public AbstractOrderState(OrderContext orderContext) {
    
    
        this.orderContext = orderContext;
    }

    public abstract void payOrder();

    public abstract void deliver();

    public abstract void receiveGoods();
}

상태 전환을 담당하는 OrderContext 개체를 통합합니다.

2. 세 가지 상태가 있기 때문에 추상 상태 클래스를 구현하기 위해 세 가지 구체적인 상태 클래스를 만듭니다.

  • 보류중인 결제 상태 카테고리 :
package com.zwx.design.pattern.state;

public class WaitPaidOrderState extends AbstractOrderState {
    
    
    public WaitPaidOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    //相当于待支付的状态绑定了支付行为
        System.out.println("支付成功");
        this.orderContext.setState(this.orderContext.waitDeliver);//切换状态
    }

    @Override
    public void deliver() {
    
    
        System.out.println("对不起,请先付钱");
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("对不起,请先付钱");
    }
}
  • 보류중인 배송 상태 분류 :
package com.zwx.design.pattern.state;

public class WaitDeliverOrderState extends AbstractOrderState {
    
    
    public WaitDeliverOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    
        System.out.println("你已经付过钱了");
    }

    @Override
    public void deliver() {
    
    
        System.out.println("商品已发货并送达目的地");
        this.orderContext.setState(this.orderContext.receiveGoods);//切换状态
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("请稍等,商品即将发货");
    }
}
  • 수신 상태 클래스 :
package com.zwx.design.pattern.state;

public class ReceiveGoodsOrderState extends AbstractOrderState{
    
    
    public ReceiveGoodsOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    
        System.out.println("您已经付过钱啦,不要重复付钱哦");
    }

    @Override
    public void deliver() {
    
    
        System.out.println("商品已发货并送达,请不要重复发货");
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("用户已收到商品,此次交易结束");
    }
}

각 상태가 동작에 바인딩되어 있고 (여러 바인딩도 지원할 수 있음) 해당 동작이 처리 된 후 다음 상태로 흘러 가고 현재 상태에 속하지 않는 동작이 그에 따라 만들어집니다. 응답.

3. 특정 상태 간 전환을 담당 할 상태 컨텍스트 환경 클래스를 만듭니다.

package com.zwx.design.pattern.state;

/**
 * @author zwx
 * @version 1.0
 * @date 2020/10/5
 * @since jdk1.8
 */
public class OrderContext {
    
    
    AbstractOrderState waitPaid;
    AbstractOrderState waitDeliver;
    AbstractOrderState receiveGoods;

    AbstractOrderState currState;//当前状态

    public OrderContext() {
    
    
        this.waitPaid = new WaitPaidOrderState(this);
        this.waitDeliver = new WaitDeliverOrderState(this);
        this.receiveGoods = new ReceiveGoodsOrderState(this);
        currState = waitPaid;
    }

    void setState(AbstractOrderState state){
    
    
        this.currState = state;
    }

    public void payOrder(){
    
    
        currState.payOrder();
    }


    public void deliver(){
    
    
        currState.deliver();
    }

    public void receiveGoods(){
    
    
        currState.receiveGoods();
    }
}

보시다시피이 클래스에는 위임 모드의 그림자도 있습니다. 다른 동작은 처리를 위해 해당 객체에 위임되며 상태 전환 만 담당합니다.

4. 마지막으로 테스트를위한 새 테스트 클래스를 만듭니다.

package com.zwx.design.pattern.state;

public class TestState {
    
    
    public static void main(String[] args) {
    
    
        OrderContext orderContext = new OrderContext();
        orderContext.payOrder();
        orderContext.deliver();
        orderContext.receiveGoods();
    }
}

출력 결과는 다음과 같습니다.

支付成功
商品已发货并送达目的地
用户已收到商品,此次交易结束

상태 모드 역할

위의 예에서 상태 모델에 세 가지 주요 역할이 있다는 결론을 내릴 수 있습니다.

  • 컨텍스트 : 클라이언트에 필요한 인터페이스를 정의하고 현재 상태의 인스턴스를 내부적으로 유지하며 특정 상태의 전환을 담당합니다.
  • 추상 상태 역할 (State) : 각 상태에서 해당 동작을 정의합니다. 하나 이상의 동작이있을 수 있습니다.
  • 구체적인 상태 역할 (ConcreteState) : 상태에 해당하는 동작을 구체적으로 실현하고 필요할 때 상태 전환을 실현합니다.

상태 모드 및 책임 체인 모드

이 상태 모드의 구현은 하나의 체인에서 처리되는 책임 모드 체인 과 유사한 것 같습니다 . 특정 시나리오에서 두 모드가 서로를 대체 할 수 있다고 할 수 있지만 두 모드도 본질적으로 다릅니다.

  • 상태 모드 : 상태 모드
    의 다음 노드는 이미 각 상태 개체에 의해 이해되며 상태 전송은 내부적으로 수행되며 클라이언트가 결정할 수 없습니다.
  • 책임 체인 모델
    의 "링크"에있는 객체는 다음 노드 프로세서가 누구인지 모르지만 클라이언트 자체에 의해 결정됩니다.

상태 모드 및 전략 모드

상태 모드와 전략 모드 를 모두 사용하여 많은 if / else 시나리오를 제거 할 수 있지만 근본적인 차이점이 있습니다. 전략 모드의 각 전략은 독립적이며 상호 교체가 가능하며 하나의 전략을 선택하면 수요를 충족 할 수 있으며 고객이 선택합니다. 상태 모드 클라이언트는 초기 노드 만 선택할 수 있으며 이후에는 자동으로 진행되며 각 상태는 전체이며 서로 대체 할 수있는 상태는 없습니다.

상태 모드 애플리케이션 시나리오

객체의 상태를 제어하는 ​​조건식이 너무 복잡 할 경우 상태 모드 사용을 고려할 수 있습니다. 상태 판단 논리를 서로 다른 상태를 나타내는 일련의 클래스로 전달하여 복잡한 논리를 단순화하고 객체를 만들 수 있습니다. 의 동작은 상태에 따라 다르며 상태가 변경되면 동작이 변경됩니다.
상태 모드는 주로 다음 시나리오에서 사용됩니다.

  • 1. 상태가 변경됨에 따라 개체의 동작을 변경해야하는 경우.
  • 2. 연산 상태에 따라 많은 양의 if / else 로직을 작성해야 할 때

상태 모드의 장단점

이점:

  • 1. 각 상태를 독립적 인 객체로 설정하면 코드에서 많은 if / else 분기가 제거되어 코드가 더 간결하고 유지 관리가 쉬워집니다.
  • 2. 서로 다른 상태는 서로 다른 클래스로 표시되므로 숫자 나 문자열로 표시 할 때보 다 상태 전환이 더 직관적이고 변환 목적이 더 명확 해집니다.
  • 3. 각 지위 클래스의 책임은 단일하고 명확하며 확장하기 쉽습니다.

불리

  • 1. 상태가 너무 많으면 클래스 확장이 발생합니다 (사실 이것은 대부분의 디자인 패턴에서 공통적 인 문제이기도합니다).
  • 2. 상태 모드의 구조와 구현은 상대적으로 복잡하여 코드 혼동을 쉽게 일으킬 수 있습니다.
  • 3. 상태 전환을 지원하는 상태 클래스는 일단 상태가 수정되거나 중간에 상태를 추가해야하는 경우 해당 소스 코드를 수정해야하며 그렇지 않으면 상태 전환 오류가 발생하기 때문에 열기 및 닫기 원칙을 위반합니다.

요약하자면

이 기사에서는 주로 상태 패턴의 정의를 소개하고 간단한 예제를 통해 간단한 상태 패턴을 구현합니다. 마지막으로 상태 패턴과 책임 체인 패턴을 비교 및 ​​분석하고 상태 패턴과 책임 체인 패턴의 차이점을 명확히합니다.

나에게 관심을 기울이고 고독한 늑대와 함께 배우고 발전하십시오 .

추천

출처blog.csdn.net/zwx900102/article/details/109202186