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