一、定義:
????????定義一個操作中的算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
二、結構:
? ? ? ? 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.父類修改影響子類