【设计模式】模板方法、策略模式以及状态模式

本专栏将从基础开始,循序渐进,由浅入深讲解常见的设计模式,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址:设计模式实战
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。

1 模板方法

package design;

abstract class AbstractClass{
    
    
    protected void step1(){
    
    
        System.out.println("AbstractClass:step1");
    }

    protected void step2(){
    
    
        System.out.println("AbstractClass:step2");
    }

    protected void step3(){
    
    
        System.out.println("AbstractClass:step3");
    }

    public final void templateMethod(){
    
    
        this.step1();
        this.step2();
        this.step3();
    }
}

class ConcreteClassA extends AbstractClass{
    
    
    @Override
    protected void step1() {
    
    
        System.out.println("ConcreteClassA:step1");
    }
}

public class Client {
    
    
    public static void main(String[] args) {
    
    
        AbstractClass abc = new ConcreteClassA();
        abc.templateMethod();
    }
}

2 策略模式

2.1 常用方法(与工厂结合,map存放)

package Design;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

interface IPromotionStrategy{
    
    
    void doPromotion();
}

class CouponStrategy implements IPromotionStrategy{
    
    

    public void doPromotion() {
    
    
        System.out.println("使用优惠券折扣");
    }
}

class GroupbuyStrategy implements IPromotionStrategy{
    
    

    public void doPromotion() {
    
    
        System.out.println("返现,直接打款到支付宝账号");
    }
}

class EmptyStrategy implements IPromotionStrategy{
    
    

    public void doPromotion() {
    
    
        System.out.println("无优惠");
    }
}

class PromotionStrategyFactory{
    
    
    private static Map<String,IPromotionStrategy> PROMOTIONS = new HashMap<String,IPromotionStrategy>();
    private static final IPromotionStrategy EMPTY = new EmptyStrategy();
    static {
    
    
        PROMOTIONS.put(PromotionKey.COUPON,new CouponStrategy());
        PROMOTIONS.put(PromotionKey.GROUPBUY,new GroupbuyStrategy());
    }

    private interface PromotionKey{
    
    
        String COUPON = "COUPON";
        String GROUPBUY = "GROUPBUY";
    }

    public static IPromotionStrategy getPromotionStragy(String promotionKey){
    
    
        IPromotionStrategy strategy = PROMOTIONS.get(promotionKey);
        return strategy == null ? EMPTY : strategy;
    }

    public static Set<String> getPromotionKeys(){
    
    
        return PROMOTIONS.keySet();
    }
}

public class client {
    
    
    public static void main(String[] args) {
    
    
        
    }
    
    public static void main2(String[] args) {
    
    
        System.out.println(PromotionStrategyFactory.getPromotionKeys());
        IPromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStragy("COUPON");
        promotionStrategy.doPromotion();
    }
}

2.2 使用不同策略初始化内部成员

package Design;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

interface IPromotionStrategy{
    
    
    void doPromotion();
}

class CouponStrategy implements IPromotionStrategy{
    
    

    public void doPromotion() {
    
    
        System.out.println("使用优惠券折扣");
    }
}

class GroupbuyStrategy implements IPromotionStrategy{
    
    

    public void doPromotion() {
    
    
        System.out.println("返现,直接打款到支付宝账号");
    }
}

class EmptyStrategy implements IPromotionStrategy{
    
    

    public void doPromotion() {
    
    
        System.out.println("无优惠");
    }
}


class PromotionActivity{
    
    
    private IPromotionStrategy strategy;

    public PromotionActivity(IPromotionStrategy strategy) {
    
    
        this.strategy = strategy;
    }

    public void execute(){
    
    
        strategy.doPromotion();
    }
}

public class client {
    
    
    public static void main(String[] args) {
    
    
        PromotionActivity activity = new PromotionActivity(new CouponStrategy());
        activity.execute();
    }


}

3 状态模式

引入依赖

<dependency>
             <groupId>org.springframework.statemachine</groupId>
             <artifactId>spring-statemachine-core</artifactId>
<!--             <version>3.0.1</version>-->
             <version>2.0.1.RELEASE</version>
         </dependency>
package com.example.pattern17_statemachine01_simple;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.persist.DefaultStateMachinePersister;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.statemachine.support.DefaultStateMachineContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

//订单状态
enum OrderStatus{
    
    
    //待支付,待发货,待收货,订单结束
    WAIT_PAYMENT,WAIT_DELIVER,WAIT_RECEIVE,FINISH;
}

//订单状态改变事件
enum OrderStatusChangeEvent{
    
    
    //支付,发货,确认收货
    PAYED,DELIVERY,RECEIVED
}

/**
 * 订单状态机配置
 */
@Configuration
@EnableStateMachine(name = "orderStateMachine")
class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderStatus, OrderStatusChangeEvent> {
    
    

    /**
     * 配置状态
     * @param states
     * @throws Exception
     */
    public void configure(StateMachineStateConfigurer<OrderStatus, OrderStatusChangeEvent> states) throws Exception {
    
    
        states
                .withStates()
                .initial(OrderStatus.WAIT_PAYMENT)
                .states(EnumSet.allOf(OrderStatus.class));
    }

    /**
     * 配置状态转换事件关系
     * @param transitions
     * @throws Exception
     */
    public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderStatusChangeEvent> transitions) throws Exception {
    
    
        transitions
                .withExternal().source(OrderStatus.WAIT_PAYMENT).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAYED)
                .and()
                .withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIT_RECEIVE).event(OrderStatusChangeEvent.DELIVERY)
                .and()
                .withExternal().source(OrderStatus.WAIT_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED);
    }

    /**
     * 持久化配置
     * 在实际使用中,可以配合Redis等进行持久化操作
     * @return
     */
    @Bean
    public DefaultStateMachinePersister persister(){
    
    
        return new DefaultStateMachinePersister<>(new StateMachinePersist<Object, Object, Order>() {
    
    
            @Override
            public void write(StateMachineContext<Object, Object> context, Order order) throws           Exception {
    
    
                //此处并没有进行持久化操作
            }

            @Override
            public StateMachineContext<Object, Object> read(Order order) throws Exception {
    
    
                //表示要使用的状态是order中的哪个属性,这里是status属性
                return new DefaultStateMachineContext(order.getStatus(), null, null, null);
            }
        });
    }
}

@Component("orderStateListener")
@WithStateMachine(name = "orderStateMachine")
class OrderStateListenerImpl{
    
    

    //当发生从source到target状态转换时调用
    @OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER")
    public boolean payTransition(Message<OrderStatusChangeEvent> message) {
    
    
        System.out.println("处理付款");
        Order order = (Order) message.getHeaders().get("order");
        order.setStatus(OrderStatus.WAIT_DELIVER);
        System.out.println("支付,状态机反馈信息:" + message.getHeaders().toString());
        return true;
    }

    @OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
    public boolean deliverTransition(Message<OrderStatusChangeEvent> message) {
    
    
        Order order = (Order) message.getHeaders().get("order");
        order.setStatus(OrderStatus.WAIT_RECEIVE);
        System.out.println("发货,状态机反馈信息:" + message.getHeaders().toString());
        return true;
    }

    @OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
    public boolean receiveTransition(Message<OrderStatusChangeEvent> message){
    
    
        Order order = (Order) message.getHeaders().get("order");
        order.setStatus(OrderStatus.FINISH);
        System.out.println("收货,状态机反馈信息:" + message.getHeaders().toString());
        return true;
    }
}



@Data
class Order{
    
    
    private int id;
    private OrderStatus status;
}

interface IOrderService{
    
    
    //创建新订单
    Order create();
    //发起支付
    Order pay(int id);
    //订单发货
    Order deliver(int id);
    //订单收货
    Order receive(int id);
    //获取所有订单信息
    Map<Integer,Order> getOrders();
}


@Service("orderService")
class OrderServiceImpl implements IOrderService {
    
    

    //    @Autowired
    @Resource
    private StateMachine<OrderStatus, OrderStatusChangeEvent> orderStateMachine;

    @Autowired
    private StateMachinePersister<OrderStatus, OrderStatusChangeEvent, Order> persister;

    private int id = 1;
    private Map<Integer, Order> orders = new HashMap<>();

    public Order create() {
    
    
        Order order = new Order();
        order.setStatus(OrderStatus.WAIT_PAYMENT);
        order.setId(id++);
        orders.put(order.getId(), order);
        return order;
    }

    public Order pay(int id) {
    
    
        Order order = orders.get(id);
        System.out.println("线程名称:" + Thread.currentThread().getName() + " 尝试支付,订单号:" + id);
        //header中要有对应的状态
        Message message = MessageBuilder.withPayload(OrderStatusChangeEvent.PAYED).
                setHeader("order", order).build();
        if (!sendEvent(message, order)) {
    
    
            System.out.println("线程名称:" + Thread.currentThread().getName() + " 支付失败, 状态异常,订单号:" + id);
        }
        return orders.get(id);
    }

    public Order deliver(int id) {
    
    
        Order order = orders.get(id);
        System.out.println("线程名称:" + Thread.currentThread().getName() + " 尝试发货,订单号:" + id);
        if (!sendEvent(MessageBuilder.withPayload(OrderStatusChangeEvent.DELIVERY)
                .setHeader("order", order).build(), orders.get(id))) {
    
    
            System.out.println("线程名称:" + Thread.currentThread().getName() + " 发货失败,状态异常,订单号:" + id);
        }
        return orders.get(id);
    }

    public Order receive(int id) {
    
    
        Order order = orders.get(id);
        System.out.println("线程名称:" + Thread.currentThread().getName() + " 尝试收货,订单号:" + id);
        if (!sendEvent(MessageBuilder.withPayload(OrderStatusChangeEvent.RECEIVED)
                .setHeader("order", order).build(), orders.get(id))) {
    
    
            System.out.println("线程名称:" + Thread.currentThread().getName() + " 收货失败,状态异常,订单号:" + id);
        }
        return orders.get(id);
    }


    public Map<Integer, Order> getOrders() {
    
    
        return orders;
    }


    /**
     * 发送订单状态转换事件
     *
     * @param message
     * @param order
     * @return
     */
    private synchronized boolean sendEvent(Message<OrderStatusChangeEvent> message, Order order) {
    
    
        boolean result = false;
        try {
    
    
            orderStateMachine.start();
            //尝试恢复状态机状态
            persister.restore(orderStateMachine, order);
            //添加延迟用于线程安全测试
            Thread.sleep(500);
            result = orderStateMachine.sendEvent(message);
            //持久化状态机状态
            persister.persist(orderStateMachine, order);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            orderStateMachine.stop();
        }
        return result;
    }
}


@SpringBootApplication
public class Pattern17Statemachine01SimpleApplication {
    
    

    public static void main(String[] args) {
    
    
        Thread.currentThread().setName("主线程");
        ConfigurableApplicationContext context = SpringApplication.run(Pattern17Statemachine01SimpleApplication.class, args);

        IOrderService orderService = (IOrderService)context.getBean("orderService");
        orderService.create();
        orderService.create();
        
        orderService.pay(1);
        orderService.pay(1);


//        new Thread("客户线程"){
    
    
//            @Override
//            public void run(){
    
    
//                orderService.deliver(1);
//                orderService.receive(1);
//            }
//        }.start();
//
//        orderService.pay(2);
//        orderService.deliver(2);
//        orderService.receive(2);
//        System.out.println("全部订单状态:"+orderService.getOrders());
    }

}

猜你喜欢

转载自blog.csdn.net/Learning_xzj/article/details/125027640