设计模式之模板方法模式实战解析

本文微信公众号「AndroidTraveler」首发。

背景

最近在看《设计模式之禅》,为了能够更加深入的理解设计模式,达到学以致用。
这边记录一下自己的一些感受和看法,并结合具体代码实战来进行说明。

模板方法模式

但凡和设计模式挂上钩,我们总是会觉得「高不可攀」。
然而实际上,设计模式是基于大量实际代码的经验总结,它来自于实际的代码。
与其说「高不可攀」,其实它反而是比较「接地气」。
而模板方法模式相信你看完本篇文章之后,会发现,原来这就是模板方法模式,然后就去看你之前的代码了。

小例子初识模板方法模式

理解设计模式最好的方法就是通过项目开发中的实际场景来说明。

大家做 Android 开发的时候写 Activity 应该都会看到下面类似代码吧?

private void getIntents() {// 从 Intent 获取传递过来的一些参数,设置到属性中
}private void findViewById() {// 通过 findViewById 来初始化各个组件
}private void setViews() {// 给组件设置监听或者初始状态
}

假设我每个界面都这样写,那么重复代码太多了,很没必要。
虽然每个方法具体的逻辑不一样,但是都有这些操作。

这个时候我们第一个想法就是继承,抽取出一个 BaseActivity。
然后将这些通用代码都放到了 BaseActivity 里面,子类再来覆写就可以了。

但是还有一个问题,那就是,我每次都需要写下面代码:

getIntents();
findViewById();
setViews();

尤其是通用代码多的时候,有时候手误可能导致某些界面这三个方法调用顺序还不一样。
那怎么办呢?我们可以抽取出一个方法,这个方法代表了这三个方法统一的调用顺序,这样就不怕手误写错了。
而这个方法就是我们的模板方法

public abstract class BaseActivity extends Activity {/*** 从 Intent 获取传递过来的一些参数,设置到属性中*/protected abstract void getIntents();/*** 通过 findViewById 来初始化各个组件*/protected abstract void findViewById();/*** 给组件设置监听或者初始状态*/protected abstract void setViews();/*** 模板方法*/final public void init() {getIntents();findViewById();setViews();}
}

这样我后面的 Activity 都可以继承这个 BaseActivity,然后只需要调用 init 方法即可。
至于不同的 Activity 的逻辑我再在三个方法里面各自实现即可。

钩子方法

一听到这个词,是不是觉得有点「高大上」,似乎很 NB?
然而,听完我后面的讲述,你内心估计
16cdd2f75dd6ac5d?w=255&h=255&f=png&s=41949

我们上面的方法里面,并不是所有的 Activity 都有其他 Activity 传递数据过来的,因此 getIntents 这个方法不一定所有子类都要调用。
这个时候我们可以提供一个钩子方法,改动部分代码如下:

/*** 模板方法*/
final public void init() {if (isGetIntents()) {getIntents();}findViewById();setViews();
}/*** 钩子方法,是否需要设置数据,默认为 true* @return*/
protected boolean isGetIntents() {return true;
}

可以看到,通过钩子方法,当我们默认需要获取数据时,什么都不用改动,如果我们不需要获取数据,只需要覆写我们的钩子方法 isGetIntents 并返回 false 即可。

好了,有了初步的印象之后,接下来就正式的加深了解吧。

16add3eca3d46bbf?w=640&h=480&f=jpeg&s=26634

定义

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

简单的说就是父类定义了一个模板方法,在这个模板方法里面有一些特定的步骤。具体的步骤实现留给子类去处理。

父类的模板方法保持了各个子类的共性,模板方法里面的步骤使得每个子类都有自己的个性。

通用代码实现

父类:

public abstract class AbstractPatternClass {/*** 基本方法,模板方法里面调用*/protected abstract void firstModule();/*** 基本方法,模板方法里面调用*/protected abstract void secondModule();/*** 模板方法,多个基本方法组合*/final public void templateMethod() {firstModule();secondModule();}
}

具体子类:

public class ConcreteClass extends AbstractPatternClass {@Overrideprotected void firstModule() {// TODO 子类实现自己的逻辑}@Overrideprotected void secondModule() {// TODO 子类实现自己的逻辑}
}

场景使用类:

public class PatternTest {public static void main(String[] args) {AbstractPatternClass abstractPatternClass = new ConcreteClass();// 调用模板方法abstractPatternClass.templateMethod();}
}

钩子方法我们上面已经说过了,相信聪明的你知道如何使用,这里就不再赘述了。

注意点

父类中的基本方法尽量设计为 protected 类型,符合迪米特法则。
父类中的模板方法一般设置为 final,不允许子类覆写。这样的目的一个是为了避免子类恶意操作,一个是为了模板的共性。

应用

当你在写代码经常用到复制和粘贴快捷键时,你就要考虑是不是可以进行抽取。
当你修改一个地方的时候,发现其他地方也要连带修改,也需要考虑一下。
多个子类有公共方法,并且逻辑基本相同。
复杂的一些算法之类的,可以让子类通过基本方法传递一些参数,核心逻辑放在模板方法里面。
重构项目的时候,也可以考虑一下把相同代码抽取到父类,通过钩子方法定制化模板。

结语

最后一点就是注意不要滥用设计模式,不要为了设计而设计

参考资料
设计模式之禅(第2版)

16bc08e14696aba3?w=900&h=500&f=png&s=231181

转载于:https://www.cnblogs.com/nesger/p/11444583.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第96:SVM简介与简单应用

详细推到见:https://blog.csdn.net/v_july_v/article/details/7624837 python实现方式: 转载于:https://www.cnblogs.com/invisible2/p/11448307.html

matlab如何把选中区域标亮

下面给出的是初始图像为彩色图像的情况。 %% Example on how to color select pixels in an image. % Kawahara (2013).% The original COLOR image. origImg imread(1.jpg); oldorigImg origImg; % Make sure the values are within 0-255. origImg uint8(origImg);% View…

Calendar是日历类

Calendar是日历类,在Date后出现,替换掉了许多Date的方法。该类将所有可能用到的时间信息封装为静态成员变量,方便获取。 Calendar为抽象类,由于语言敏感性,Calendar类在创建对象时并非直接创建,而是通过静态…

玩转大数据21:基于FP-Growth算法的关联规则挖掘及实现

1.引言 关联规则挖掘是大数据领域中重要的数据分析任务之一,其可以帮助我们发现数据集中项目之间的关联关系。关联规则挖掘是指在交易数据或者其他数据集中,发现一些常见的关联项,如购物篮中经常一起出现的商品组合。关联规则挖掘的应用非常…

MATLAB – TreeBagger example

In MATLAB, Decision Forests go under the rather deceiving name of TreeBagger. 随机森林分类器(Random Forest) B TreeBagger(nTree,train_data,train_label,Method,classification); predict_label predict(B,test_data); 利用随机…

第95:PCA

输入数据矩阵->计算每条记录的平均值和标准差->计算协方差矩阵->得到协方差矩阵的所有特征值和特征向量->对特征值进行从大到小的排序,并且得到与之对应的特征向量 PCA是无监督的。没有标签也可以做,是基于方差的。 精髓在于将协方差矩阵进行…

国外少儿PYTHON编程书推荐

1,Python for Kids: A Playful Introduction to Programming 中文版已结有了,叫做 趣学Python——教孩子学编程 51wK-ZIUImL 亚马逊上人气很高,适合10岁以上儿童,内容浅显易懂,非常适合儿童入门 2,He…

将sublime text3添加到右键菜单中(可执行)

安装了sublime text3,发现右键文件里面没有使用sublime text3打开的选项,所以需要手动添加使用sublime text3编辑的选项。 打开注册表编辑器。 开始——>运行——>regedit 选择HKEY_CLASSES_ROOT——>*——>shell,右键&#…

以股票RSI指标为例,学习Python发送邮件功能(含RSI指标确定卖点策略)

本人之前写过若干“给程序员加财商”的系列文,目的是通过股票案例讲述Python知识点,让大家在学习Python的同时还能掌握相关的股票知识,所谓一举两得。 在之前的系列文里,大家能看到K线,均线,成交量的案例&a…

不用去验血,对照这张表,就能知道自己缺啥!千万收藏好!

很多时候 身体上出现问题 不用去医院就能知道自己缺什么 对照下面的清单 能让你省下大笔钱 身体健康少生病 赶紧看看吧 1.看 头 1.头发发黄、发焦,缺蛋白质; 2.头发稀疏无光,补蛋白质和维生素A; 3.防止白发,补叶酸、泛…

从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (三)

本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一)从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (二)从图(Graph)到图卷积(Graph Convolution)&#x…

Photoshop 手动画金标准流程

下面给出Photoshop手动画金标准的流程, 1. 读取 图片 2. 找到套锁按钮 3. 利用套锁按钮手动画金标准 4. 点击套锁区域,右键新建图层 此时可以看到右侧出现新建的图层1 5. 在套锁区域添加颜色 此时可以直接选择软件右下角的背景和前景的颜色都选择为…

肺部胸片图像掩膜和伪彩色处理matlab

clc; clear; close all; Iimread(006.jpg);%读取图像 I double(I); figure(1),imshow(I,[]) figure(2),imshow(I,colormap) colorbar% newimg I; II imread(006_mixture.gif); III imresize(II,0.5); figure(3),imshow(III)mask im2bw(III, 0.5); figure(4),imshow(mask…

给 Flutter 界面切换来点特效

本文微信公众号「AndroidTraveler」首发。 背景 我们知道页面之间如果直接切换,会比较生硬,还会让用户觉得很突兀,用户体验不是很好。 因此一般情况下,页面之间的切换为了达到平滑过渡,都会添加动画。 另外&#xff0c…

生成高斯图像

本文转自 http://www.cnblogs.com/tiandsp/archive/2012/02/26/2368533.html clear; m31; n31; imgzeros(m1,n1); imgdouble(img); pi3.1415926; sigma10; for i-(m/2):m/2for j-(n/2):n/2img(im/21,jn/21)(1/(2*pi*sigma*sigma))*exp(-(i*ij*j)/(2*sigma*sigma)); end end i…

高斯模糊的算法(高斯权重)

本文转自:http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html 通常,图像处理软件会提供”模糊”(blur)滤镜,使图片产生模糊的效果。 “模糊”的算法有很多种,其中有一种叫做”高斯模糊“&…

序列化流与反序列化流

序列化流与反序列化流 用于从流中读取对象的 操作流 ObjectInputStream 称为 反序列化流 用于向流中写入对象的操作流 ObjectOutputStream 称为 序列化流 特点:用于操作对象。可以将对象写入到文件中,也可以从文件中读取对象。 1 对象序列化流Objec…

图像相似性搜索的原理

本文转自: 相似图片搜索的原理 相似图片搜索的原理(二) http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html http://blog.s…

灰度共生矩阵(GLCM)并计算能量、熵、惯性矩、相关性(matlab)(待总结)

关于灰度共生矩阵的介绍可参考 http://blog.csdn.net/chuminnan2010/article/details/22035751 http://blog.csdn.net/xuezhisd/article/details/8908824 http://blog.csdn.net/xuexiang0704/article/details/8713204 http://cn.mathworks.com/help/images/ref/imlincomb.h…

机器学习之 weka学习(一)weka介绍,安装和配置环境变量

本部分详情可查看博客http://blog.csdn.net/u011067360/article/details/20844443 数据挖掘开源软件:WEKA基础教程 Weka简介: Weka是由新西兰怀卡托大学开发的智能分析系统(Waikato Environment for Knowledge Analysis) 。在怀…