Template Method模式
意图:定义一个操作中的骨架,而将一些步骤延迟到子类中。Template Method模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
问题:需要遵循一个过程或一系列步骤,它们在某个具体层次上保持一致,但单个步骤在更详细的层次上可能有不同的实现。
解决方案:允许定义不同的子步骤,同时维护基本过程的一致性。
参与者和协作者:Template Method模式包括一个定义基本Template Method方法的抽象类,这个抽象类中的虚拟方法需要被重载。每个派生自这个抽象类的具体类为这个模板实现一套新的方法。
效果:模板为代码复用提供了一个优秀的平台。它们还有助于确保需要的步骤得到实现。它们为每个具体类将重载后的步骤捆绑在一起,因此只有在这些重载方法总是并且只能一起发生时,才应该使用Template Method模式。
实现:创建一个抽象类,用抽象方法实现一个过程。这些抽象方法必须在子类中得到实现,用以执行过程的每个步骤,如果这些步骤各自独立变化,那么每个步骤都可以用Strategy模式实现。
模板类是继承关系中一种很重要的实现
比如手头的android项目里面有个listiew用到的adapter,其它的都一样,就是对点击的处理不同,我自己实际上是用接口实现的
在这里我也把用模板方法实现一下,把共用的方法放到模板里面,将onclick的具体实现放在Concrete Class里面,也就是MyListItem里面就行了,
注意:模板类和单纯的继承区别就在于模板是用abstract修饰的,abstract是不能new的,这点大家应该很清楚,
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package templatemethod;
/**
*
* @author blacklaw
*/
public class TemplateMethod {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println("main Go");
MyListItem mListItem = new MyListItem();
mListItem.getView();
}
static class MyListItem extends ListItem{
@Override
protected void onClick() {
System.out.println("MyListItem.onClick");
}
}
}
/**
*
* @author blacklaw
*/
abstract class ListItem{
public void getView(){
System.out.println("ListItem.getView");
onClick();
}
protected abstract void onClick();
}
接口实现
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package templatemethod;
/**
*
* @author blacklaw
*/
public class InterfaceMethod {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println("main Go");
IListItem mListItem = new IListItem(new ActionManager());
mListItem.getView();
}
static class ActionManager implements IListItem.ListItemClick{
@Override
public void onClick() {
System.out.println("InterfaceMethod.onClick");
}
}
}
/**
*
* @author blacklaw
*/
class IListItem{
public interface ListItemClick{
public void onClick();
}
ListItemClick listItemClick;
IListItem(ListItemClick click){
listItemClick = click;
}
public void getView(){
System.out.println("ListItem.getView");
listItemClick.onClick();
}
}
接口实现和模板实现的几个不同
1.模板只能取模板内部的variable计算,而接口实现可以调用接口manager的变量,与外界交互更加方便!当然,你自己传到模板里面的变量不算
2.一个接口的管理类可以实现多个接口,而对于不同的onClick,模板的实现需要多个子类,显得很复杂!
3.简要概括一下接口和抽象,
接口是为了在一个事物上实现更多功能,
比如让电脑实现不同的接口,使它可以被不同的设备调用,它实现了鼠标的接口,那么就可以被鼠标调用
抽象是为了让子类更加具体的实现某个功能,比如抽象了一个USB类,那么鼠标就可以具体化为USB接口的Mouse
class Computer implements Mouse.MouseInterface{
String name = "computer_001";
@Override
public void move(){
System.out.println(name + "mouse move");
}
}
class USB{
}
class Mouse extends USB{
public interface MouseInterface{
public void move();
}
MouseInterface MI;
Mouse(MouseInterface i){
MI = i;
MI.move();
}
}
至于是选择用接口还是抽象,一般看被暴露出来的功能和那块的数据打交道,如果是父类的数据肯定用extends
如果是外部数据,就用implements