Android设计模式之模板方法模式
一、定义:
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
二、结构:
AbstractClass抽象类:定义算法的骨架,包含模板方法和若干基本方法(抽象方法、具体方法、钩子方法)。
ConcreteClass具体子类:实现抽象类中的抽象方法,覆盖某些具体方法或钩子方法以定制算法的步骤。
三、代码示例:
1.抽象模板类
public abstract class DataExporter {
// 模板方法(final禁止覆盖)
public final void exportData(List<String> data, String filename) {
if (validateData(data)) {
String formattedData = formatData(data); // 抽象方法
writeToFile(formattedData, filename); // 抽象方法
sendNotification(); // 钩子方法
}
}
// 抽象方法(子类必须实现)
protected abstract String formatData(List<String> data);
protected abstract void writeToFile(String content, String filename);
// 具体方法(默认实现)
protected boolean validateData(List<String> data) {
return data != null && !data.isEmpty();
}
// 钩子方法(子类可选覆盖)
protected void sendNotification() {
// 默认不发送通知
}
}
2.具体子类
// 导出为 CSV 格式
public class CsvExporter extends DataExporter {
@Override
protected String formatData(List<String> data) {
return String.join(",", data); // 转换为 CSV
}
@Override
protected void writeToFile(String content, String filename) {
try (FileWriter writer = new FileWriter(filename)) {
writer.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
// 覆盖钩子方法(导出后发送通知)
@Override
protected void sendNotification() {
System.out.println("CSV文件导出完成!");
}
}
// 导出为 JSON 格式
public class JsonExporter extends DataExporter {
@Override
protected String formatData(List<String> data) {
return "{ \"data\": " + data.toString() + " }"; // 简化的JSON格式
}
@Override
protected void writeToFile(String content, String filename) {
try (FileWriter writer = new FileWriter(filename)) {
writer.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.使用模板方法
public class Main {
public static void main(String[] args) {
List<String> data = Arrays.asList("Apple", "Banana", "Cherry");
// 导出为 CSV
DataExporter csvExporter = new CsvExporter();
csvExporter.exportData(data, "data.csv");
// 导出为 JSON
DataExporter jsonExporter = new JsonExporter();
jsonExporter.exportData(data, "data.json");
}
}
四、应用场景:
1.多个子类有相同流程但部分步骤不同,如文件导出,网络请求。
2.需要控制子类的扩展点,如钩子方法。
3.框架设计,如Activity的生命周期,AsyncTask。
五、优缺点:
优点:
1.代码复用,避免重复算法流程;
2.扩展性强,子类只需关注差异步骤;
3.封装不变部分,提升可维护性。
缺点:
1.灵活性受限,算法流程固定;
2.继承强耦合,违法合成复用原则
3.父类修改影响子类