博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式笔记(二)——模板方法模式
阅读量:7064 次
发布时间:2019-06-28

本文共 3175 字,大约阅读时间需要 10 分钟。

hot3.png

1. 需求矛盾

l  同一个父类的几个子类在实现某些功能时具有大多数共同点,但各个子类之间还有不同点。

l  比如三个儿子从事不同的工作,都会赚钱,都知道孝顺父母,但每个人赚钱的方式不同。

思考:

1)  三个儿子的共同点是什么?

2)  三个儿子的相异点是什么?

3)  如何设计可以使三个儿子同时具有共同点,而又能保证每个人的不同点?

 

2. 是什么——定义

定义一个模板结构,将具体内容延迟到子类去实现。

3. 为什么——特点

1)  提高代码的复用性

2)  实现反向控制(子类决定功能)

4. 什么时候用——适用性

1)  一些方法通用,却在每一个子类都重新写了这一方法。

2)  有多个子类共有的方法,且逻辑相同。

3)  重要的、复杂的方法,可以考虑作为模板方法。

5. UML图

201025_1Qn9_3041734.png

6. 怎么用——使用方法

需求:

抄书与印书

以前没有印刷技术的时候,老师念,学生抄,抄完再背。

存在的问题:万一学生抄错题目了,找书都找不到了!

6.1  没有任何原则的初始设计

public class Demo1 {    public static void main(String[] args) {        new Book1().show();        new Book2().show();        new Book3().show();    }}class Book1 {    public void show() {        System.out.println("学生1抄的书——题目。。。");        System.out.println("学生1抄的书——正文。。。");        System.out.println("学生1抄的书——封皮。。。");    }}class Book2 {    public void show() {        System.out.println("学生2抄的书——题目。。。");        System.out.println("学生2抄的书——正文。。。");        System.out.println("学生2抄的书——封皮。。。");    }}class Book3 {    public void show() {        System.out.println("学生3吵的书——题日。。。");        System.out.println("学生3吵的书——正文(没抄完)。。。");        System.out.println("学生3吵的书——封皮。。。");    }}

因为学生3没有抄完(而且抄的题目还写错了。。。),以至于之后要背书的时候怎么也背不对了。。。

6.2  抽取公共代码,封装方法

为了避免上面连题目都能抄错,需要把相同的代码提取出来:

abstract class AbstractBook {    public void showTitle() {        System.out.println("题目。。。");    }        public void showFace() {        System.out.println("封皮。。。");    }}class Book4 extends AbstractBook {    public void show() {        showTitle();        System.out.println("学生4抄的书——正文。。。");        showFace();    }}class Book5 extends AbstractBook {    public void show() {        showTitle();        System.out.println("学生5抄的书——正文。。。");        showFace();    }}

但这样仍存在问题:每个子类需要调用抄题目、封皮的方法,万一忘了呢。。。

6.3  应用模板方法模式

将子类需要抄的正文抽取成一个方法,父类单独写一个模板方法,用于抄题目和封皮:

class AbstractBook {    public void showIncomplateBook() {        System.out.println("题目。。。");        function();        System.out.println("封皮。。。");    }        public void function(){    }}class Book6 extends AbstractBook {    @Override    public void function() {        System.out.println("正文(抄完了)。。。");    }}

但这样还是会出现问题:万一忘了抄正文呢。。。

而且,父类的function里摆着个空壳,也不像回事吧。。。

这时就需要使用一套机制,强制子类抄!————抽象方法

abstract class AbstractBook {    public void showIncomplateBook() {        System.out.println("题目。。。");        function();        System.out.println("封皮。。。");    }        public abstract void function();}class Book7 extends AbstractBook {    @Override    public void function() {        System.out.println("被逼着抄的正文。。。");    }}

加入抽象方法后,子类不得不重写父类的未实现方法,否则无法编译通过。

 

这套思想可以使用在SSH项目中的dao层的通用抽取:

BaseDaoImpl负责实现全部查询和条件查询的框架,但具体的条件查询,要通过每个模块自己实现,所以这里需要设置模板方法(查全部,返回查询结果)和抽象方法(自定义查询条件)。

模拟代码(跑不动哦,别打我,手动滑稽)

public abstract class BaseDaoImpl {    public Object getAll(Object o) {        StringBuilder sb = new StringBuilder("select * from tbl_???");        doQuery(sb, o);        return sb.toString();    }        public abstract void doQuery(StringBuilder sb, Object o);}public class DepartmentDaoImpl extends BaseDaoImpl {    @Override    public void doQuery(StringBuilder sb, Object o) {        /*DepartmentQueryModel dqm = ()o;        if (condition) {                    }*/    }}

 

转载于:https://my.oschina.net/LinkedBear/blog/1786481

你可能感兴趣的文章
文件管理相关命令
查看>>
Guava库学习:学习使用Strings和Charsets类
查看>>
学习strings、strconv包
查看>>
如何在Sharepoint Online中创建调查问卷
查看>>
Exchange 2013公网证书配置
查看>>
Java开发在线打开编辑保存Word文件
查看>>
将学习进行到底!为普通人的奋斗送福
查看>>
常用十大python机器学习库
查看>>
TCP/IP三次握手四次挥手
查看>>
Systemstate Dump分析经典案例(下)
查看>>
PHPcms怎么调用二级栏目
查看>>
中小型网络构建案例——防火墙的应用
查看>>
《Linux就该这么学》 第3章 管道符、重定向与环境变量
查看>>
Okhttp3使用
查看>>
交换的江湖
查看>>
ubuntu16.04 双网卡绑定
查看>>
lLinux学习笔记之apache及论坛的发布
查看>>
上三角
查看>>
C# 多线程学习系列二
查看>>
简单词法分析器的实现
查看>>