상태 모드의 원리 분석
디자인 패턴 시리즈 목록
디자인 패턴 | 항공권 |
---|---|
세 가지 공장 모델 | 탑승 입구 |
전략 모드 | 탑승 입구 |
위임 모드 | 탑승 입구 |
템플릿 방법 패턴 | 탑승 입구 |
관찰자 모드 | 탑승 입구 |
싱글 톤 모드 | 탑승 입구 |
프로토 타입 모드 | 탑승 입구 |
대행사 모델 | 탑승 입구 |
데코레이터 모드 | 탑승 입구 |
어댑터 모드 | 탑승 입구 |
빌더 모드 | 탑승 입구 |
책임 사슬 모델 | 탑승 입구 |
플라이급 모델 | 탑승 입구 |
조합 모드 | 탑승 입구 |
외관 패턴 | 탑승 입구 |
브리지 모드 | 탑승 입구 |
중개 모델 | 탑승 입구 |
반복자 모드 | 탑승 입구 |
상태 모드 | 탑승 입구 |
통역사 모드 | 탑승 입구 |
메모 모드 | 탑승 입구 |
명령 모드 | 탑승 입구 |
방문자 모드 | 탑승 입구 |
소프트웨어 디자인의 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. 상태 전환을 지원하는 상태 클래스는 일단 상태가 수정되거나 중간에 상태를 추가해야하는 경우 해당 소스 코드를 수정해야하며 그렇지 않으면 상태 전환 오류가 발생하기 때문에 열기 및 닫기 원칙을 위반합니다.
요약하자면
이 기사에서는 주로 상태 패턴의 정의를 소개하고 간단한 예제를 통해 간단한 상태 패턴을 구현합니다. 마지막으로 상태 패턴과 책임 체인 패턴을 비교 및 분석하고 상태 패턴과 책임 체인 패턴의 차이점을 명확히합니다.
나에게 관심을 기울이고 고독한 늑대와 함께 배우고 발전하십시오 .