学习DP--2.模版方法模式
模版方法模式这个模式不是在看书的时候学到的,而我自己最近在做一个小应用的时候,重构完代码后总结的,翻开书一看,才知道,咦,这原来是模版方法模式。想想,《设计模式》这本书的作者们也是从大量的实践中总结出这些经验,如果我们一开始能够尝试的去使用这些经验,也许可以减少我们走的弯路。
记录一下我代码的重构过程和模版方法模式:
一开始的类有:
http://dl.iteye.com/upload/attachment/0073/1778/1d115a3f-83f1-34c9-a35b-3bc73f68328b.png
DataSource代表了界面上所需数据的来源,提供加载,操作,保存数据的方法。BaseDataSource作为基类,定义了一些抽象方法让子类实现。后来子类要完成一个判断,要是有网络连接就优先使用网络下载,如果没有网络连接再使用本地数据。于是在子类中出现这样的代码:
private void localLoad(Context context){ if(NetworkUtil.isConntected()){ //notify user the data was downloaded from net. downLoad(context); }else{ //do operations that loading data from local. }}private void localLoad(Context context){ if(NetworkUtil.isConntected()){ //do operations that loading data from net. }else{ //notify user the data was loaded from local. localLoad(context); }}
看着子类中这些代码,我感觉有点纠结了。子类为什么要重复这些逻辑呢?于是我试着去修改这些代码。既然子类都重复了这个逻辑,那么可以把他上拉到父类中。
接下来就在父类中添加了一个方法
类图如下:
http://dl.iteye.com/upload/attachment/0073/1788/6bb2a99a-ff41-3cb7-8c3d-3bf4c686d6d6.png
父类的代码如下:
public abstract class BaseDataSource{ //some fields...... //some methods...... //this method is final in order to keep subclasses from overriding it. public final void load(Context context){ if(NetworkUtil.isConntected()){ //notify user the data was downloaded from net. downLoad(context); }else{ //notify user the data was loaded from local. localLoad(context); } } //these methods is protected...(Java的protected,你们懂的) protected abstract void localLoad(Context context); protected abstract void downLoad(Context context);}
我当时想,这样设计一来,父类完成上述所需要的逻辑判断,并调用相应的方法,但并不关心方法的实现细节;而子类就只需要实现父类中两个抽象的方法就可以了,却不用重复判断逻辑;并且界面在需要获取数据时只需要调用load方法,完全不需要关心数据是怎么得来的。
这样看代码,好像确实比以前好多了。
后来在看书的时候,看到模版方法模式,又回想起这次重构,这不一样嘛。呵呵o(∩_∩)o
在《设计模式》中说道:
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.
大概的意思就是:
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模版方法使得子类不可以改变一个算法的结构即可重定义该算法的某些特定步骤。
做法大概就像上面那样了。在父类中定义好算法的框架,对算法中的可变部分提取出合适的虚函数,由子类实现。这样就实现了把算法的特定步骤延迟到子类中实现,子类可以改变算法的特定步骤,却不改变算法的框架。
当然也可以有一些变形嘛。比如,如果可变方法太多,而子类不一定要复写全部虚方法,那可以考虑在父类为某些方法提供一些默认版本。
又一个简单的例子:
比如排序,可以依据大小排序。有时想由小到大排,有时候又想由大到小排。这时候就额可以用模版方法了,而不是为两种情况都编写一种排序方法。(代码在BBCode编辑器里直接编写的,不知道有木有Bug。(*^__^*) 。而且这个排序完全可以有更简单的方法,在java中有提供这样的机制让我们简单的就实现这一效果。)
public class Sort{ public final void sort(int[]array){ int length = array.length; int lengthsub1 = length - 1; for(int i = 0;i<lengthsub1;i++){ for(int j = i;j<length;j++){ if(compare(array,array)>0){ int temp = array; array = array; array = temp; } } } } /** * if a larger that b,return a positive number,if b larger than a return negative number,if a equal to b,return 0. */ protected abstract int compare(int a,int b);}//由小到大public void SortBySmall extends Sort{ @Overrideprotected int compare(int a,int b){ if(a > b) return 1; else if(a < b) return -1; else return 0;}}//由大到小public void SortByLarge extends Sort{ @Overrideprotected int compare(int a,int b){ if(a > b) return -1; else if(a < b) return 1; else return 0;}}
我是菜鸟,我犯错我开心,希望大家能不吝指教,谢谢啦!
转载请注明来自:http://zhenzxie.iteye.com/blog
页:
[1]