常用设计模式的实际工作使用

单例模式

饿汉式单例模式:
springboot启动会加载Bean到容器里,后续调用都用同一个实例,相关注解@Componet , @Bean , @Service等等,线程安全,因为类加载的时候已经实例化了,不用加锁,执行效率高,但会占用内存。

@Slf4j
@Component
public class SingleDemo {

    public SingleDemo() {
      log.info("初始化单例");
    }

    public String doSome(){
        return "123";
    }

}

懒汉式单例模式:
需要用到时才进行加载,什么时候用就什么时候new实例,因为线程不安全,所以需要加锁,效率比饿汉式差,但需要用时才加载,节省空间。

@Slf4j
@Component
@Lazy
public class SingleDemo {

    public SingleDemo() {
      log.info("初始化单例");
    }

    public String doSome(){
        return "123";
    }

}

策略模式+工厂模式:实现促销执行

/**
 * 促销策略
 * */
public interface PromStrategy {

    void executeProm();

}

实现策略类,分别有满减优惠和折扣促销,后续每增加一种促销方式就新增一个策略类

@Slf4j
@Service("favour")
public class FavourStrategy implements PromStrategy{
    @Override
    public void executeProm() {
       log.info("执行优惠促销");
    }
}
@Slf4j
@Service("discount")
public class DiscountStrategy implements PromStrategy{
    @Override
    public void executeProm() {
        log.info("执行折扣促销");
    }
}

使用Spring工厂管理各个策略类

@Slf4j
@Component
public class PromService implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        PromService.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static PromStrategy getStrategy(String className){
        PromStrategy promStrategy = null;
        try {
            promStrategy = (PromStrategy) applicationContext.getBean(className);
        }catch (Exception e){
            log.error("找不到Bean");
        }
        return promStrategy;
    }
}
@Service
public class ExecutePromServiceImpl implements ExecutePromService{
    @Override
    public void executePromStrategy() {
        PromStrategy strategy = PromService.getStrategy("favour");
        //执行促销
        strategy.executeProm();
    }
}

责任链模式

public interface Process{
    void executeProcess();
}
public abstract class AbstractProcess implements Process {
    @Override
    public void executeProcess() {}
}
@Slf4j
public class ApprovalProcess extends AbstractProcess{
    @Override
    public void executeProcess() {
        log.info("执行审批流程!");
    }
}
@Slf4j
public class SubmitProcess extends AbstractProcess{
    @Override
    public void executeProcess() {
      log.info("执行提交流程!");
    }
}
public class DefaultProcessChain implements ProcessChain{

    private List<Process> processList;

    public DefaultProcessChain() {
        this.processList = new ArrayList<>();
    }

    @Override
    public ProcessChain add(Process process) {
        processList.add(process);
        return this;
    }

    @Override
    public void executeProcess() {
        for(Process process:processList){
            process.executeProcess();
        }
    }
}
public class DefaultProcessChainBuilder {

    private static ProcessChain chain;

    private DefaultProcessChainBuilder(){
        throw new AssertionError();
    }

    public synchronized static ProcessChain build(){
        if(!ObjectUtils.isEmpty(chain)){
            return chain;
        }
        chain = new DefaultProcessChain();
        chain.add(new SubmitProcess());
        chain.add(new ApprovalProcess());
        return chain;
    }
}
@Service
public class ProcessServiceImpl implements ProcessService{
    @Override
    public void executeProcess() {
        DefaultProcessChainBuilder.build().executeProcess();
    }
}

适配器模式:实现旧接口的二次封装

  • 场景:目前手上有一套1.0的老代码
  • 需要在这个老代码的基础上构建新代码,但要提供接口给别人面向新接口开发
  • 所以需要适配器模式,别人实现的是v2.0,内部是v1.0,调用也是v2.0
  • 实际应用场景:例如基于第三方类库,Redis ES提供的API,我们可以通过
  • 适配器模式去把Redis的API适配到我们开发的接口,进行二次封装
  • get、set、mset、mget,一套接口;适配器,DAORedisImpl就是一个适配器,
  • 这个适配器实现的是我们的DAO接口,
  • 在我们的save、update、remove等方法中,去调用redis客户端的get、set、mset、mget等方法。
  • 这里的旧接口就相当于redis提供的API,我们可以注入在我们想适配的接口中
@Slf4j
@Service
public class StockServiceV2Impl extends StockServiceImpl implements StockService{

    @Override
    public void updateStock() throws Exception {
        log.info("新逻辑执行");
        //旧逻辑执行
        super.updateStock();
    }
}
@Slf4j
@Service
public class StockServiceImpl implements StockService {

    @Autowired
    private PayOrderStockCommandFactory payOrderStockCommandFactory;

    @Override
    public void updateStock() throws Exception {
        log.info("更新库存");
        StockUpdatper stockUpdatper = payOrderStockCommandFactory.create();
        stockUpdatper.updateStock();
    }

}

状态模式:实现订单状态流转

适合场景,数据有状态,状态就一定会流转,从状态1变成状态2
将不同的状态要执行的代码逻辑封装在不同的state类中
有一个context类,负责根据传入的参数,决定这份数据的状态流转到什么状态
同时负责执行那个新状态的代码逻辑

public interface State {
    //变更状态操作
    void changeState();
}
@Slf4j
public class NewState implements State{
    @Override
    public void changeState() {
         log.info("订单新建状态");
    }
}
@Slf4j
public class ApprovedState implements State{
    @Override
    public void changeState() {
        log.info("订单更改为:待审批状态");
    }
}
@Slf4j
public class FinishState implements State{
    @Override
    public void changeState() {
        log.info("订单状态变更为:已完成状态");
    }
}
public class StateContext {

    private State status;

    public StateContext(State state) {
        this.status=state;
        this.status.changeState();
    }

    public void executeChange(Integer type){
        if(type==1){
            this.status = new ApprovedState();
        }else if(type==2){
            this.status = new FinishState();
        }
        this.status.changeState();
    }

    public static void main(String[] args) {
        StateContext stateContext = new StateContext(new NewState());
        stateContext.executeChange(1);
    }
}

模板方法模式:实现门店或营运区的限购逻辑

把通用运算逻辑和特殊运算逻辑拆分,特殊逻辑分别区分在门店和营运区的操作

public interface LimitBuyService {
    //限购操作
    void calculate();
}
@Slf4j
public abstract class AbstractLimitBuyTemplate implements LimitBuyService{
    @Override
    public void calculate() {
       specificCalculate();
       commonCalculate();
    }

    private void commonCalculate(){
      log.info("执行通用逻辑");
    }

    protected abstract void specificCalculate();
}
@Slf4j
@Service
public class RegionLimitCalculate extends AbstractLimitBuyTemplate{

    @Override
    protected void specificCalculate() {
        log.info("执行营运区限购运算逻辑");
    }
}
@Slf4j
@Service
public class StoreLimitCalculate extends AbstractLimitBuyTemplate{
    @Override
    protected void specificCalculate() {
      log.info("执行门店限购逻辑");
    }
}

模板方法模式+工厂方法模式+命令模式:实现库存更新

例如更新库存这个操作,可以把更新库存的通用流程和方法封装成一个模版,把通用的部分在抽象模板写好,特殊计算部分,例如提交订单,退款入库,采购入库,每一个独立的命令可以继承该父类去执行独立的方法

@Slf4j
public abstract class AbstractStockUpdatper implements StockUpdatper{

    private StockMapper stockMapper;

    public AbstractStockUpdatper(StockMapper stockMapper) {
         this.stockMapper=stockMapper;
    }

    @Override
    public void updateStock(){
        executeUpdateStock();
        executeUpdateStockStatus();
        setCommandType();
    }

    /**
     * 特殊计算逻辑-设置更新的执行命令
     * 区别于提交订单,退款入库,采购入库等等命令
     * */
    protected abstract void setCommandType() throws Exception;

    /**
     * 通用模板方法-更新状态
     * */
    private void executeUpdateStockStatus(){
        log.info("执行通用模板方法-更新状态");
    }

    /**
     * 实际执行更新库存操作
     * */
    private void executeUpdateStock(){
        log.info("执行更新数据库库存操作");
        stockMapper.executeUpdateStock();
    }
}

使用命令模式,让命令继承模板方法,重写对应的特殊操作

@Slf4j
@Component
public class PayOrderStockCommand extends AbstractStockUpdatper{

    public PayOrderStockCommand(StockMapper stockMapper) {
        super(stockMapper);
    }

    /**
     * 执行模板特殊方法
     * */
    @Override
    protected void setCommandType() throws Exception {
        log.info("完成更新库存,设置该库存更新操作为支付订单");
    }
}

通过使用工厂模式构建对应的命令对象

public class PayOrderStockCommandFactory extends AbstractStockUpdatperFactory{

    @Autowired
    private StockMapper stockMapper;

    @Override
    public StockUpdatper create() {
        log.info("构建命令");
        return new PayOrderStockCommand(stockMapper);
    }
}

执行命令操作

@Slf4j
@Service
public class StockServiceImpl implements StockService {

    @Autowired
    private PayOrderStockCommandFactory payOrderStockCommandFactory;

    @Override
    public void updateStock() throws Exception {
        log.info("更新库存");
        StockUpdatper stockUpdatper = payOrderStockCommandFactory.create();
        stockUpdatper.updateStock();
    }
    
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值