3)钩子方法的使用
1.概述
钩子方法的引入使得子类可以控制父类的行为。
2.结构图
3.代码实现
将公共方法和框架代码放在抽象父类中
abstract class DataViewer {//抽象方法:获取数据public abstract void GetData();//具体方法:转换数据public void ConvertData() {System.out.println("将数据转换为XML格式。");}//抽象方法:显示数据public abstract void DisplayData();//钩子方法:判断是否为XML格式的数据public boolean IsNotXMLData() {return true;}//模板方法public void Process() {GetData();//如果不是XML格式的数据则进行数据转换if (IsNotXMLData()) {ConvertData();}DisplayData();}
}
钩子方法为IsNotXMLData(),其返回类型为boolean类型,在子类中可以根据实际情况覆盖该方法。
显示XML格式数据的具体子类XMLDataViewer
public class XMLDataViewer extends DataViewer {//实现父类方法:获取数据@Overridepublic void GetData() {System.out.println("从XML文件中获取数据。");}//实现父类方法:显示数据,默认以柱状图方式显示,可结合桥接模式来改进@Overridepublic void DisplayData() {System.out.println("以柱状图显示数据。");}//覆盖父类的钩子方法@Overridepublic boolean IsNotXMLData() {return false;}
}
在具体子类XMLDataViewer中覆盖了钩子方法IsNotXMLData(),返回false,表示该数据已为XML格式,无须执行数据转换方法ConvertData()。
客户端代码如下
public class Client {public static void main(String[] args) {DataViewer dv;dv = new XMLDataViewer();dv.Process();}
}
4)总结
1.优点
-
在父类中定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
-
可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行。
-
在模板方法模式中通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便。
2.缺点
需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象,可结合桥接模式进行设计。
3.适用场景
-
对复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,将可以改变的细节由其子类来实现。
-
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
-
需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。