设计模式(java)--模版方法模式之任务分配
转自:http://blog.csdn.net/zhengzhb/article/details/7405608
定义:定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤。
类型:行为类模式
类图:

事实上,模版方法是编程中一个经常用到的模式。先来看一个例子,某日,程序员A拿到一个任务:给定一个整数数组,把数组中的数由小到大排序,然后把排序之后的结果打印出来。经过分析之后,这个任务大体上可分为两部分,排序和打印,打印功能好实现,排序就有点麻烦了。但是A有办法,先把打印功能完成,排序功能另找人做。
abstract class AbstractSort {
/**
* 将数组array由小到大排序
* @param array
*/
protected abstract void sort(int[] array);
public void showSortResult(int[] array){
this.sort(array);
System.out.print("排序结果:");
for (int i = 0; i < array.length; i++){
System.out.printf("%3s", array[i]);
}
}
}
写完后,A找到刚毕业入职不久的同事B说:有个任务,主要逻辑我已经写好了,你把剩下的逻辑实现一下吧。于是把AbstractSort类给B,让B写实现。B拿过来一看,太简单了,10分钟搞定,代码如下:
class ConcreteSort extends AbstractSort {
@Override
protected void sort(int[] array){
for(int i=0; i<array.length-1; i++){
selectSort(array, i);
}
}
private void selectSort(int[] array, int index) {
int MinValue = 32767; // 最小值变量
int indexMin = 0; // 最小值索引变量
int Temp; // 暂存变量
for (int i = index; i < array.length; i++) {
if (array[i] < MinValue){ // 找到最小值
MinValue = array[i]; // 储存最小值
indexMin = i;
}
}
Temp = array[index]; // 交换两数值
array[index] = array[indexMin];
array[indexMin] = Temp;
}
}
写好后交给A,A拿来一运行:
public class Client {
public static int[] a = { 10, 32, 1, 9, 5, 7, 12, 0, 4, 3 }; // 预设数据数组
public static void main(String[] args){
AbstractSort s = new ConcreteSort();
s.showSortResult(a);
}
}
运行结果:
排序结果: 0 1 3 4 5 7 9 10 12 32
运行正常。行了,任务完成。没错,这就是模版方法模式。大部分刚步入职场的毕业生应该都有类似B的经历。一个复杂的任务,由公司中的牛人们将主要的逻辑写好,然后把那些看上去比较简单的方法写成抽象的,交给其他的同事去开发。这种分工方式在编程人员水平层次比较明显的公司中经常用到。比如一个项目组,有架构师,高级工程师,初级工程师,则一般由架构师使用大量的接口、抽象类将整个系统的逻辑串起来,实现的编码则根据难度的不同分别交给高级工程师和初级工程师来完成。怎么样,是不是用到过模版方法模式?
模版方法模式的结构
模版方法模式由一个抽象类和一个(或一组)实现类通过继承结构组成,抽象类中的方法分为三种:
- 抽象方法:父类中只声明但不加以实现,而是定义好规范,然后由它的子类去实现。
- 模版方法:由抽象类声明并加以实现。一般来说,模版方法调用抽象方法来完成主要的逻辑功能,并且,模版方法大多会定义为final类型,指明主要的逻辑功能在子类中不能被重写。
- 钩子方法:由抽象类声明并加以实现。但是子类可以去扩展,子类可以通过扩展钩子方法来影响模版方法的逻辑。
- 抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,因为抽象类的好坏直接决定了程序是否稳定性。
实现类用来实现细节。抽象类中的模版方法正是通过实现类扩展的方法来完成业务逻辑。只要实现类中的扩展方法通过了单元测试,在模版方法正确的前提下,整体功能一般不会出现大的错误。
模版方法的优点及适用场景
容易扩展。一般来说,抽象类中的模版方法是不易反生改变的部分,而抽象方法是容易反生变化的部分,因此通过增加实现类一般可以很容易实现功能的扩展,符合开闭原则。
便于维护。对于模版方法模式来说,正是由于他们的主要逻辑相同,才使用了模版方法,假如不使用模版方法,任由这些相同的代码散乱的分布在不同的类中,维护起来是非常不方便的。
比较灵活。因为有钩子方法,因此,子类的实现也可以影响父类中主逻辑的运行。但是,在灵活的同时,由于子类影响到了父类,违反了里氏替换原则,也会给程序带来风险。这就对抽象类的设计有了更高的要求。
在多个子类拥有相同的方法,并且这些方法逻辑相同时,可以考虑使用模版方法模式。在程序的主框架相同,细节不同的场合下,也比较适合使用这种模式。
设计模式(java)--模版方法模式之任务分配的更多相关文章
- JS常用的设计模式(10)——模版方法模式
模式方法是预先定义一组算法,先把算法的不变部分抽象到父类,再将另外一些可变的步骤延迟到子类去实现.听起来有点像工厂模式( 非前面说过的简单工厂模式 ). 最大的区别是,工厂模式的意图是根据子类的实现最 ...
- 设计模式 笔记 模版方法模式 Template Method
//---------------------------15/04/28---------------------------- //TemplateMethod 模版方法模式----类行为型模式 ...
- 设计模式之模版方法模式(Template Method Pattern)
一.什么是模版方法模式? 首先,模版方法模式是用来封装算法骨架的,也就是算法流程 既然被称为模版,那么它肯定允许扩展类套用这个模版,为了应对变化,那么它也一定允许扩展类做一些改变 事实就是这样,模版方 ...
- JAVA设计模式之模版方法模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述模板方法(Template Method)模式的: 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式 ...
- java设计模式之模版方法模式以及在java中作用
模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有 ...
- 【java设计模式】(10)---模版方法模式(案例解析)
一.概念 1.概念 模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式. 它定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的 ...
- Java设计模式の模版方法模式
概述 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的 ...
- NET设计模式 第二部分 行为型模式(15):模版方法模式(Template Method)
摘要:Template Method模式是比较简单的设计模式之一,但它却是代码复用的一项基本的技术,在类库中尤其重要. 主要内容 1.概述 2.Template Method解说 3..NET中的Te ...
- Head First 设计模式笔记(模版方法模式)
1.定义: 在一个方法中定义一个算法骨架,而将一些步骤延迟到子类中.模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 2.类图: 3.说明: 模版方法可以理解为一个方法里面包 ...
随机推荐
- bc显示小数点前的0
bc是强大而常用的计算工具.不过在除法运算时,如果得到的结果值小于1,得到的小数前面的0不存.本篇提供几个常用小数点前缺0的解决方法. [root@maqing ~]# bc bc Copyright ...
- MySQL重启端口被占用处理
1,查看日志的ERROR 2018-05-23T01:26:59.230382Z 0 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set. 201 ...
- 安装scikit-image问题
参考地址: Image Processing Using Python https://code.tutsplus.com/tutorials/image-processing-using-pytho ...
- sqlserver并发处理,锁和事务
本文系转载,谢谢:http://www.cnblogs.com/cxd4321/archive/2008/12/10/1351792.html 另外这个也不错 http://www.cnb ...
- Entity Framework API介绍 -- DbSet<>().Find()
过去我们常常使用Where或First(FirstOrDefault)方法来查找对应的实体,比如: var query = context.CertInfoMakeDetails.ToList().W ...
- [lua]判断nginx收到的是否json
local post_data = ngx.req.get_body_data() --[[ngx.log(ngx.ERR, 'post data:', post_data)]] local ok, ...
- 走了很多弯路的CCScrollView
最近在学习Cocos2d-x,学习CCScrollView的时候走了很多弯路,决定记录下来. 学习cocos2d-x的最大的困惑就是资料不是很齐全,网上有很多资料,但是版本差异大,其次深度低,讲解不够 ...
- python+selenium+Firefox+pycharm版本匹配
window(2018-05-29)最新 python:3.6.1 地址https://www.python.org/downloads/release/python-361/ selenium ...
- C++常见错误坑洞
指针没初始化就使用*解引用运算符; 连续delete释放new指针; 使用delete 是否常规普通变量内存; 地址直接复制给制作
- c++Builder Delphi XML 解析例子
XMLDocument; Xml.XMLIntf.hpp Xml.XMLDoc.hpp #include "Xml.Win.msxmldom.hpp" XMLDocument控件 ...