zoukankan      html  css  js  c++  java
  • 设计模式-模板模式

    模板模式一般适用于有一定的流程,而且在不同的业务场景中有着不同的流程实现的情况。发布流程涉及到编译,备份,SQL执行,部署。这种情况下模板模式是一个不错的选择。

    模板模式有时可以和组合模式一块使用,可以更能体现出Java面向接口编程的特性。

    首先定义三个接口,分别代表流程中的不同的业务步骤

    public interface StepOne {
    
        void doStepOne();
    }
    public interface StepTwo {
        
        void doStepTwo();
    }
    public interface StepThree {
    
        void doStepThree();
    }

    合并这些接口,用一个接口来代表所有接口,避免后面会有大量的冗余接口代码

    public interface FullStep extends StepOne, StepTwo, StepThree {
    }

    接下来是定义模板,这里我会先定义一个规范模板的接口

    public interface Process {
        void process();
    //    Process nextProcess();
    }

    具体 模板实现

    public abstract class ProcessImpl implements Process {
    
        private StepOne stepOne;
    
        private StepTwo stepTwo;
    
        private StepThree stepThree;
    
    
        @Override
        public void process() {
    
            if (stepOne != null) {
    
                stepOne.doStepOne();
            }
    
            if (stepTwo != null) {
                stepTwo.doStepTwo();
            }
    
            if (stepThree != null) {
                stepThree.doStepThree();
            }
    
            if (nextProcess() != null) {
                nextProcess().process();
            }
        }
    
    
        abstract Process nextProcess();
    }

    在抽象类ProcessImpl中,需要注入流程接口声明,这里我定义了三步,这里的

    private StepOne stepOne;

    private StepTwo stepTwo;

    private StepThree stepThree;

    怎么注入进去呢,由于这三个接口会被后面每一个具体的实现类实现,那么注入就是这些实现类共同要做的事情,所以可以把注入放在它们的公共父类来实现。所以我们需要一个公共父类

    public abstract class FullProcess extends ProcessImpl implements FullStep {
    
        public void init() {
            setStepOne(this);
            setStepTwo(this);
            setStepThree(this);
        }
    
    }

    通过调用init方法便可以实现注入实现类对象到模板类的字段当中,这里还差一点,需要把这个类的调用自动化,那么需要用到spring的扩展接口。

    public class OrderProcess extends FullProcess implements FullStep {
    
    
        @PostConstruct
        public void initialize() {
            super.init();
        }
    
        @Override
        Process nextProcess() {
            return null;
        }
    
        @Override
        public void doStepOne() {
    
        }
    
        @Override
        public void doStepThree() {
    
        }
    
        @Override
        public void doStepTwo() {
    
        }
    }

    这里我才用的是@PostConstruct注解,当然也可以采用实现InitializingBean接口,重写afterPropertiesSet()方法来实现。

    OrderProcess公共实现创建完成后,便可以实现我们每一种流程对应的接口了,这里我实现了两个模板实现类。

    public class ApProcess extends OrderProcess {
    
        @Override
        public void doStepOne() {
            System.out.println("AP step 1");
        }
    
        @Override
        public void doStepThree() {
            System.out.println("AP step 3");
        }
    
        @Override
        public void doStepTwo() {
            System.out.println("AP step 2");
        }
    }
    public class CenterProcess extends OrderProcess {
    
        @Override
        public void doStepOne() {
            System.out.println("Center step 1");
        }
    
        @Override
        public void doStepThree() {
            System.out.println("Center step 3");
        }
    
        @Override
        public void doStepTwo() {
            System.out.println("Center step 2");
        }
    }

    下面测试下

    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class ProcessTeset {
    
        @Autowired
        private ApplicationContext applicationContext;
    
        @Test
        public void test() {
            for (ProcessEnum value : ProcessEnum.values()) {
                Process process = (Process) applicationContext.getBean(value.getType());
                process.process();
            }
        }
    }

    测试结果

    在这整个流程中,使用了模板模式和组合模式,具体的逻辑下沉的子类中实现。但是由于模板中的流程被拆分成了各个接口,所以需要把子类的实现注入到模板的属性中去,这样不仅可以规范模板的流程,还分离了流程中的每一个节点,比较方便。如果后期需要加节点,那么只需要加一个接口即可;如果需要修改节点逻辑,只需要修改接口签名或者修改实现类即可。总之可以做到流程的动态化。

    详细的代码传到了GitHub上https://github.com/markytsai/design-demos。

  • 相关阅读:
    真正的e时代
    在线手册
    UVA 10616 Divisible Group Sums
    UVA 10721 Bar Codes
    UVA 10205 Stack 'em Up
    UVA 10247 Complete Tree Labeling
    UVA 10081 Tight Words
    UVA 11125 Arrange Some Marbles
    UVA 10128 Queue
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/markytsai/p/13443245.html
Copyright © 2011-2022 走看看