zoukankan      html  css  js  c++  java
  • 模板方法模式 之 实际生产使用方式

      模板方式模式可以说是设计模式中比较简单的一类,简单的说其实现过程是多态的扩展,为什么这么说呢?下面具体介绍一下模板方法模式的概念及实际生产使用情况。(理解不到位请见谅啊!)

      模板方法模式简单的说就是抽象父类定义抽象方法及运作流程,子类继承以实现具体工作。举个简单的例子: 男生洗头和女生洗头之间的差别,(以不洗澡,只洗头为例)首先对洗头这件事情主要有一下几个流程: 准备---->挤洗发液---->清洗---->吹干(比较邋遢,洗一次就行了)。

    public abstract class WashHair {
        //准备阶段
        protected abstract void prepare();
        //挤洗发液
        protected abstract void extrudedShampoo();
        //清洗
        protected abstract void wash();
        //吹干
        protected abstract void dry();
        //流程
        public void templateMethod() {
            prepare();
            extrudedShampoo();
            wash();
            dry();
        }
    }

      那么到男生开始洗头了,流程如下: 脱衣服(光膀子)----> 拧起沐浴露---->一顿抓----->风干。

    public class ManWashHair extends WashHair {
    
        @Override
        protected void prepare() {
            // TODO Auto-generated method stub
            System.out.println("光着膀子");
        }
    
        @Override
        protected void extrudedShampoo() {
            // TODO Auto-generated method stub
            System.out.println("拧起沐浴露");
        }
    
        @Override
        protected void wash() {
            // TODO Auto-generated method stub
            System.out.println("一顿狂抓");
        }
    
        @Override
        protected void dry() {
            // TODO Auto-generated method stub
            System.out.println("自然风干");
        }
    
    }

      男生洗头比较粗糙,不讲究。现在女生开始洗头,当然肯定不能脱光膀子是吧,准备(不能耍流氓,过程不说了)---->选择洗发液---->按摩清洗(其实估计也没这么讲究)---->吹风机。

    public class WamanWashHair extends WashHair{
    
        @Override
        protected void prepare() {
            // TODO Auto-generated method stub
            System.out.println("准备");
        }
    
        @Override
        protected void extrudedShampoo() {
            // TODO Auto-generated method stub
            System.out.println("选择洗发液,护发素");
        }
    
        @Override
        protected void wash() {
            // TODO Auto-generated method stub
            System.out.println("按摩清洗");
        }
    
        @Override
        protected void dry() {
            // TODO Auto-generated method stub
            System.out.println("吹风机吹干");
        }
    
    }

      好,现在基本代码都写完了,我们先说好处再来测试。优点: 解耦,首先我们不在直接操作男生或者女生这个对象,而是操作我们的抽象类。其次方便扩展,这一点很重要,比如在公司里面有一个流程很多业务都需要使用,但是每一个业务都自己编写相同的一套流程太low了,而且新的业务增加时还需要再写一遍重复的流程,如果使用模板方法模式,就可以直接扩展,在调用的时候直接调用就行。缺点:增加了代码的可阅读性,为什么这么说?简单的解释,这样子类的实现过程直接影响父类的执行结果。

      测试一下:

    public class WashMain {
        public static void main(String[] args) {
            //将子类向上转型为父抽象类
            WashHair manWashHair = new ManWashHair();
            WashHair womanWashHair = new WomanWashHair();
            //男女生分别执行洗头
            manWashHair.templateMethod();
            womanWashHair.templateMethod();
        }
    }

      现在模板方法工厂学习完成,那么在实际生产中会不会这么搞呢?其实也可以,但是不灵活,给大家介绍原来一个项目的解决方案,使用xml来解决。在上面的例子中我们发现我们建立的模板是方法层面上面的,就是说直接调用的是方法,但是在实际生产中则侧重于类层面的(不知道这么说是不是符合专业用语啊!),同时也有方法侧面,下面给大家介绍一个建房的例子(自己想的,如果业务逻辑不对的话就将就看吧)。

      建房需要这么几个步骤,买地---->准建审批---->招募工程队---->修建,这样一个详细的过程,其中涉及到公司修建和个人修建(小城市)。下面简单介绍一下两者不同的实现过程,

        首先公司买地需要开会,造价计算,而个人则是衡量自身的经济水平,准备资金。

        准建审批,公司需要提供公司资历,提交修建保证金,个人则需要提交保证金,请领导吃饭。

        招募工程队,公司需要招标,投标公司资历审核,决标成交,个人则需要打听哪个包工头技术好,商讨价格即可。

      下面是详细的实现过程。

      针对买地,审批,招募,修建的代码不做展示,将代码的目录结构放出来。

      

      具体看看build的过程,通过Build入口方法build来执行,通过spring setter方法注入buyLand,audit,conscribe的不同实现类(分为company和person)。

    package com.module.entry;
    
    import com.module.audit.Audit;
    import com.module.buyland.BuyLand;
    import com.module.conscribe.Conscribe;
    
    /**
     * 
     * Project Name:Model
     * ClassName:Build
     * Description:
     * @author: libo
     * @date: 2018年11月10日 下午4:54:42
     * note:主要完成修建的过程,在类的层面上实现模板方法模式
     *
     */
    public class Build {
        //通过spring注入
        private BuyLand buyLand;
        
        private Audit audited;
        
        private Conscribe conscribe;
        
        //具体修建过程
        public void build() {
            buyLand.excute();
            audited.excute();
            conscribe.excute();
        }
    
        public BuyLand getBuyLand() {
            return buyLand;
        }
    
        public void setBuyLand(BuyLand buyLand) {
            this.buyLand = buyLand;
        }
    
        public Audit getAudited() {
            return audited;
        }
    
        public void setAudited(Audit audit) {
            this.audited = audit;
        }
    
        public Conscribe getConscribe() {
            return conscribe;
        }
    
        public void setConscribe(Conscribe conscribe) {
            this.conscribe = conscribe;
        }
        
    }

      下面是spring的配置文件,通过spring的配置文件可以轻松的决定整个修建过程的注入类,这样方便修改和扩展。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <!-- 采用xml注入的方式分别注入buyLand,Audit,conscribe的实现类 也可以配置自动扫描来进行注解注入 两种方式都可以-->
        <bean id="companyBuyLand" class="com.module.buyland.CompanyBuyLand"></bean>
        
        <bean id="personBuyLand" class="com.module.buyland.PersonBuyLand"></bean>
        
        <bean id="companyAudited" class="com.module.audit.CompanyAudited"></bean>
        
        <bean id="personAudited" class="com.module.audit.PersonAudited"></bean>
        
        <bean id="companyConscribe" class="com.module.conscribe.CompanyConscribe"></bean>
        
        <bean id="personConscribe" class="com.module.conscribe.PersonConscribe"></bean>
        <!--通过注入不同的实现类来完成不同的工作--> 
        <bean id="personBuild" class="com.module.entry.Build">
            <property name="buyLand" ref="personBuyLand"></property>
            <property name="audited" ref="personAudited"></property>
            <property name="conscribe" ref="personConscribe"></property>
        </bean>       
        <bean id="companyBuild" class="com.module.entry.Build">
            <property name="buyLand" ref="companyBuyLand"></property>
            <property name="audited" ref="companyAudited"></property>
            <property name="conscribe" ref="companyConscribe"></property>
        </bean>       
             
            
            
            
    </beans>

      下面是main函数及运行结果:

      在原来的项目中,一个架构师使用这种方式完成订单框架的基本结构,并且完成通过spring进行流程内业务的配置,觉得很牛逼,如果我在这写的不清楚或者有错误,望见谅!如果你有更好的理解,也请留言告诉我,谢谢!

  • 相关阅读:
    11种常用css样式之background学习
    11种常用css样式之开篇文本字体学习
    学习css常用基本层级伪类属性选择器
    学习了解CSS3发展方向和CSS样式与优先级
    常见CSS3选择器和文本字体样式汇总
    简单了解css3样式表写法和优先级
    4——PHP比较&&复制运算符
    虚基类
    string类中getline函数的应用
    string类应用举例
  • 原文地址:https://www.cnblogs.com/liboBlog/p/9940194.html
Copyright © 2011-2022 走看看