设计模式讲解与代码实践(二十三)——模板方法

本文来自李明子csdn博客(http://blog.csdn.net/free1985),商业转载请联系博主获得授权,非商业转载请注明出处!

1 目的

模板方法(Template Method)模式将组成一个过程的各子过程与该过程的实现分离。

2 基本形态

模板方法的基本形态如类图2-1所示。
图2-1  模板方法类图
图2-1 模板方法类图

3 参与者

结合图2-1,下面介绍各类在模板方法设计模式中扮演的角色。
3.1 AbstractClass
AbstractClass是抽象类,实现了模版方法TemplateMethod,并声明了模版方法中需要调用的抽象方法,如类图中的抽象方法PrimitiveOperation1及抽象方法PrimitiveOperation2。
3.2 ConcreteClass
ConcreteClass是具体类,派生于AbstractClass,实现了AbstractClass中声明的抽象方法PrimitiveOperation1和PrimitiveOperation2。

4 代码实践

下面我们用一个业务场景实例来进一步讲解模板方法的使用。
4.1 场景介绍
某库存管理系统包含移库功能,可以将指定数量的商品从一个仓库移至另一个仓库。
以下各节将介绍该场景各类的具体实现及其在模板方法设计模式中所对应的参与者角色。
4.2 AbstractStorageMgmt
AbstractStorageMgmt是库存管理抽象类,实现了模版方法transfer,声明了需要子类实现的子方法add和remove。对应于模板方法模式的参与者,AbstractStorageMgmt是抽象类AbstractClass。下面的代码给出了AbstractStorageMgmt的声明。

package demo.designpattern.templatemethod;

/**
 * 库存管理抽象类
 * Created by LiMingzi on 2017/12/6.
 */
public abstract class AbstractStorageMgmt {
    /**
     * 入库
     * @param storage 仓库名称
     * @param product 产品名称
     * @param count 入库数量
     * @return 操作是否成功
     */
    public abstract boolean add(String storage,String product,int count);
    /**
     * 出库
     * @param storage 仓库名称
     * @param product 产品名称
     * @param count 出库数量
     * @return 操作是否成功
     */
    public abstract boolean remove(String storage,String product,int count);

    /**
     * 移库
     * @param srcStorage 源库名
     * @param destStorage 目标库名
     * @param product 产品名
     * @param count 数量
     * @return 操作是否成功
     */
    public boolean transfer(String srcStorage,String destStorage,String product,int count){
        if(remove(srcStorage,product,count)){
            return add(destStorage,product,count);
        }
        return false;
    }
}

上述代码中,33行,移库功能,需要将指定数量的某商品从源仓库移至目标仓库。显而易见,这个功能需要从源仓库出库和向目标仓库入库这两个子操作(34-36行)。而它们并没有在AbstraStorageMgmt中实现,而是延迟到子类中实现。这里,仅仅在15行声明了抽象方法add及在23行声明了抽象方法remove。
4.3 StorageMgmt
StorageMgmt是库存管理类,派生于抽象类AbstractStorageMgmt。对应于模板方法模式的参与者,StorageMgmt是具体类ConcreteClass。下面的代码给出了StorageMgmt的声明。

package demo.designpattern.templatemethod;

/**
 * 库存管理类
 * Created by LiMingzi on 2017/12/6.
 */
public class StorageMgmt extends AbstractStorageMgmt{
    /**
     * 入库
     *
     * @param storage 仓库名称
     * @param product 产品名称
     * @param count   入库数量
     * @return 操作是否成功
     */
    @Override
    public boolean add(String storage, String product, int count) {
        // sql语句
        String sql = "update t_storage set c_count=c_count+"+count+" where c_product='"+product+"' and c_storage = '"+storage+"'";
        System.out.println("更新库存:"+sql);
        return true;
    }

    /**
     * 出库
     *
     * @param storage 仓库名称
     * @param product 产品名称
     * @param count   出库数量
     * @return 操作是否成功
     */
    @Override
    public boolean remove(String storage, String product, int count) {
        if(count>getProductCount(storage,product)){
            return false;
        }
        // sql语句
        String sql = "update t_storage set c_count=c_count-"+count+" where c_product='"+product+"' and c_storage = '"+storage+"'";
        System.out.println("更新库存:"+sql);
        return true;
    }

    /**
     * 获取产品数量
     * @param storage
     * @param product
     * @return
     */
    private int getProductCount(String storage,String product){
        // sql语句
        String sql = "select c_count from t_storage where c_product='"+product+"' and c_storage = '"+storage+"'";
        System.out.println("查询库存:"+sql);
        return 100;
    }
}

上述代码中,17行,入库方法add实现了抽象方法,这里以sql语句输出模拟入库功能;33行出库方法remove实现了抽象方法,34行由库存是否充足决定是否可以出库。同样,这里以sql语句输出模拟出库功能。
4.4 测试代码
为了测试本文中的代码,我们可以编写如下测试代码。测试代码中,分别对学步车和餐椅两种商品做移库操作。

 /**
     * 模版方法测试
     */
    public static void templateMethodTest(){
        // 仓库管理类
        AbstractStorageMgmt storageMgmt = new StorageMgmt();
        // 移库结果1
        boolean result4TransferFromA2B = storageMgmt.transfer("仓库A","仓库B","学步车",80);
        System.out.println("从仓库A转移80件学步车到仓库B"+(result4TransferFromA2B?"成功":"失败"));
        // 移库结果2
        boolean result4TransferFromB2A = storageMgmt.transfer("仓库B","仓库A","餐椅",120);
        System.out.println("从仓库B转移120件餐椅到仓库A"+(result4TransferFromB2A?"成功":"失败"));
    }

编译运行后,得到如下测试结果:
查询库存:select c_count from t_storage where c_product=’学步车’ and c_storage = ‘仓库A’
更新库存:update t_storage set c_count=c_count-80 where c_product=’学步车’ and c_storage = ‘仓库A’
更新库存:update t_storage set c_count=c_count+80 where c_product=’学步车’ and c_storage = ‘仓库B’
从仓库A转移80件学步车到仓库B成功
查询库存:select c_count from t_storage where c_product=’餐椅’ and c_storage = ‘仓库B’
从仓库B转移120件餐椅到仓库A失败

目录 第1章UML类图实训 1.1知识讲解 1.1.1UML概述 1.1.2类与类的UML表示 1.1.3类之间的关系 1.2实训实例 1.2.1类图实例之图书管理系统 1.2.2类图实例之商场会员管理系统 1.3实训练习 第2章面向对象设计原则实训 2.1知识讲解 2.1.1面向对象设计原则概述 2.1.2单一职责原则 2.1.3开闭原则 2.1.4里氏代换原则 2.1.5依赖倒转原则 2.1.6接口隔离原则 2.1.7合成复用原则 2.1.8迪米特法则 2.2实训实例 2.2.1单一职责原则实例分析 2.2.2开闭原则实例分析 2.2.3里氏代换原则实例分析 2.2.4依赖倒转原则实例分析 2.2.5接口隔离原则实例分析 2.2.6合成复用原则实例分析 2.2.7迪米特法则实例分析 2.3实训练习 第3章创建型模式实训 3.1知识讲解 3.1.1设计模式 3.1.2创建型模式概述 3.1.3简单工厂模式 3.1.4工厂方法模式 3.1.5抽象工厂模式 3.1.6建造者模式 3.1.7原型模式 3.1.8单例模式 3.2实训实例 3.2.1简单工厂模式实例之图形工厂 3.2.2工厂方法模式实例之日志记录器 3.2.3抽象工厂模式实例之数据库操作工厂 3.2.4建造者模式实例之游戏人物角色 3.2.5原型模式实例之快速创建工作周报 3.2.6单例模式实例之多文档窗口 3.3实训练习 第4章结构型模式实训 4.1知识讲解 4.1.1结构型模式概述 4.1.2适配器模式 4.1.3桥接模式 4.1.4组合模式 4.1.5装饰模式 4.1.6外观模式 4.1.7享元模式 4.1.8代理模式 4.2实训实例 4.2.1适配器模式实例之算法适配 4.2.2桥接模式实例之跨平台视频播放器 4.2.3组合模式实例之杀毒软件 4.2.4装饰模式实例之界面显示构件库 4.2.5外观模式实例之文件加密 4.2.6享元模式实例之围棋棋子 4.2.7代理模式实例之日志记录代理 4.3实训练习 第5章行为型模式实训 5.1知识讲解 5.1.1行为型模式概述 5.1.2职责链模式 5.1.3命令模式 5.1.4解释器模式 5.1.5迭代器模式 5.1.6中介者模式 5.1.7备忘录模式 5.1.8观察者模式 5.1.9状态模式 5.1.10策略模式 5.1.11模板方法模式 5.1.12访问者模式 5.2实训实例 5.2.1职责链模式实例之在线文档帮助系统 5.2.2命令模式实例之公告板系统 5.2.3解释器模式实例之机器人控制程序 5.2.4迭代器模式实例之商品名称遍历 5.2.5中介者模式实例之温度转换器 5.2.6备忘录模式实例之游戏恢复点设置 5.2.7观察者模式实例之股票变化 5.2.8状态模式实例之银行账户 5.2.9策略模式实例之电影票打折 5.2.10模板方法模式实例之数据库操作 5.2.11访问者模式实例之奖励审批 5.3实训练习 第6章模式联用与综合实例实训 6.1设计模式补充知识 6.1.1反射与配置文件 6.1.2GRASP模式 6.1.3架构模式与MVC 6.2模式联用实训 6.2.1适配器模式与桥接模式联用 6.2.2组合模式与命令模式联用 6.2.3外观模式与单例模式联用 6.2.4原型模式与备忘录模式联用 6.2.5观察者模式与组合模式联用 6.2.6访问者模式、组合模式与迭代器模式联用 6.3综合实例实训 6.3.1多人联机射击游戏 6.3.2数据库同步系统 6.4实训练习 附录A参考答案 A.1第1章实训练习参考答案 A.2第2章实训练习参考答案 A.3第3章实训练习参考答案 A.4第4章实训练习参考答案 A.5第5章实训练习参考答案 A.6第6章实训练习参考答案 参考文献
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值