模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
// 抽象类:数据挖掘器
class DataMiner {
// 模板方法
mine(path) {
const file = this.openFile(path);
const rawData = this.extractData(file);
const data = this.parseData(rawData);
const analysis = this.analyzeData(data);
this.sendReport(analysis);
this.closeFile(file);
}
// 具体方法
openFile(path) {
console.log(`Opening file: ${path}`);
return { path };
}
closeFile(file) {
console.log(`Closing file: ${file.path}`);
}
sendReport(analysis) {
console.log("Sending report...");
console.log(analysis);
}
// 抽象方法(在JavaScript中通过抛出错误来模拟)
extractData(file) {
throw new Error("extractData must be implemented by subclasses");
}
parseData(rawData) {
throw new Error("parseData must be implemented by subclasses");
}
analyzeData(data) {
throw new Error("analyzeData must be implemented by subclasses");
}
}
// 具体类:CSV数据挖掘器
class CSVDataMiner extends DataMiner {
extractData(file) {
console.log(`Extracting data from CSV file: ${file.path}`);
return "raw,csv,data";
}
parseData(rawData) {
console.log("Parsing CSV data");
return ["parsed", "csv", "data"];
}
analyzeData(data) {
console.log("Analyzing CSV data");
return `CSV Analysis Result: ${data.join(", ")}`;
}
}
// 具体类:PDF数据挖掘器
class PDFDataMiner extends DataMiner {
extractData(file) {
console.log(`Extracting data from PDF file: ${file.path}`);
return "raw pdf data";
}
parseData(rawData) {
console.log("Parsing PDF data");
return { type: "pdf", content: "parsed pdf data" };
}
analyzeData(data) {
console.log("Analyzing PDF data");
return `PDF Analysis Result: ${data.content}`;
}
}
// 客户端代码
function clientCode(dataMiner, filePath) {
console.log("Client: Starting data mining process...");
dataMiner.mine(filePath);
}
// 使用示例
console.log("Mining CSV file:");
clientCode(new CSVDataMiner(), "data.csv");
console.log("\nMining PDF file:");
clientCode(new PDFDataMiner(), "report.pdf");
实现思路
-
DataMiner抽象类:- 定义了
mine方法,这是模板方法,它规定了数据挖掘的算法骨架。 - 包含了一些具体方法(
openFile,closeFile,sendReport),这些方法在所有子类中都是通用的。 - 定义了抽象方法(
extractData,parseData,analyzeData),这些方法需要由子类实现。
- 定义了
-
具体类
CSVDataMiner和PDFDataMiner:- 继承自
DataMiner类。 - 实现了抽象方法,提供了特定文件类型的具体实现。
- 继承自
-
客户端代码:
- 使用具体的数据挖掘器对象,调用模板方法
mine。
- 使用具体的数据挖掘器对象,调用模板方法
-
模板方法
mine:- 定义了算法的骨架,按顺序调用各个步骤。
- 一些步骤由基类实现,一些则推迟到子类中实现。
优点
- 代码复用:通用的步骤在父类中实现,避免了重复代码。
- 扩展性:可以轻松添加新的数据挖掘器类型,而不影响现有代码。
- 控制反转:父类调用子类的操作,而不是相反。
- 封装不变部分:将不变的部分封装在父类中,将可变部分留给子类实现。