在这个快节奏的世界里,一杯热腾腾的茶不仅仅能舒缓身心,还能成为理解复杂编程概念的灵感源泉。今天,我们就在这份静谧与温暖中,通过泡茶这一日常活动,轻松掌握设计模式中的经典——模板方法模式。
泡茶与编程:看似不相干,实则紧密相连
想象一下,泡茶的过程就像是编写一个程序:每个步骤都是精心策划的指令,共同完成一个任务。从烧水到加入柠檬,每一步都不可或缺,正如软件开发中的各个环节。那么,如何让这个过程变得既高效又易于维护呢?这就需要引入模板方法模式的概念。
什么是模板方法模式?
模板方法模式是一种行为设计模式,它定义了一个操作中的算法骨架,将不变的部分放在超类中,可变的部分留给子类去实现。简而言之,就是提供一个固定的流程框架,但具体实现细节交由子类决定。就像泡茶的流程固定,但选择什么茶叶、是否加糖等细节可以自由变化。
泡茶的模板方法
让我们以泡茶为例,具体看看模板方法模式是如何运作的。泡茶的步骤可以抽象为以下几个环节:
- 准备材料:确保有水、茶叶和杯子。
- 加热:把水煮沸。
- 冲泡:用沸水冲泡茶叶。
- 装杯:将茶水倒入杯子。
- 个性化调整:根据个人喜好添加柠檬或其他配料。
代码实现
伪代码
-
构造函数 Tea(type): 定义了一个构造函数,接受一个参数 type,代表茶的类型。在构造函数内部,通过 this.type = type 设置实例的茶类型,并打印出准备泡制的茶的类型信息。
function Tea(type) { this.type = type; console.log('您准备泡一杯' + this.type); } -
原型方法:
- boilWater(): 定义在 Tea.prototype 上,描述了把水煮沸的步骤。
- steepTeaBag(): 同样定义在原型上,描述了用沸水浸泡茶叶的步骤。
- pourInCup(): 描述了把茶水倒进杯子的动作。
- addLemon(): 个性化步骤,根据个人口味添加柠檬。 这些方法通过原型链共享,任何 Tea 的实例都可以访问到它们。
Tea.prototype.boilWater = function() { console.log('把水煮沸'); } // 使用prototype 将方法添加到原型中 Tea.prototype.steepTeaBag = function() { console.log('用沸水浸泡茶叶'); } Tea.prototype.pourInCup = function() { console.log('把茶水倒进杯子'); } Tea.prototype.addLemon = function() { console.log('根据个人口味添加柠檬'); } -
模板方法 init(): 在 Tea.prototype 上定义了一个模板方法,它按照一定的顺序调用了前面定义的步骤方法,形成了泡茶的标准流程。
Tea.prototype.init = function(){ this.boilWater(); this.steepTeaBag(); this.pourInCup(); this.addLemon(); } -
创建实例 lemonTea: 通过 new Tea('柠檬茶') 创建了一个 Tea 的实例,传入 '柠檬茶' 作为茶的类型。
var lemonTea = new Tea('柠檬茶'); -
调用 init() 方法: 对 lemonTea 实例调用 init() 方法,触发整个泡茶流程的执行。。
lemonTea.init(); // 调用init方法,执行模板方法
完整代码呈现
function Tea(type) {
this.type = type;
console.log('您准备泡一杯' + this.type);
}
// prototype 是js的一个特殊属性,指向原型对象
// 给Tea添加一个方法 对象prototype
Tea.prototype.boilWater = function() {
console.log('把水煮沸');
} // 使用prototype 将方法添加到原型中
Tea.prototype.steepTeaBag = function() {
console.log('用沸水浸泡茶叶');
}
Tea.prototype.pourInCup = function() {
console.log('把茶水倒进杯子');
}
Tea.prototype.addLemon = function() {
console.log('根据个人口味添加柠檬');
}
// 接口 模板方法接口。
Tea.prototype.init = function(){
this.boilWater();
this.steepTeaBag();
this.pourInCup();
this.addLemon();
}
var lemonTea = new Tea('柠檬茶');
lemonTea.init(); // 调用init方法,执行模板方法
结果
使用模板方法模式的优势
- 代码复用:通过在Tea构造函数的原型(prototype)上定义通用的泡茶步骤(如烧水、泡茶包、倒进杯子、加柠檬),所有茶的子类可以复用这些基本步骤,无需在每个子类中重复编写相同的代码。
- 灵活性:虽然这个示例中没有展示子类重写父类方法的情况,但模板方法模式允许子类覆盖或补充父类中的某些步骤。
与AIGC的融合
在AI生成内容(AIGC)日益普及的今天,模板方法模式的价值更为凸显,其价值得到了进一步的强调和提升。这种模式通过定义一个操作中的算法骨架,并允许子类重定义某些步骤,为AI生成的内容提供了结构化和可定制的框架。
代码示例
运用OpenAI API与ChatGPT模型来处理和生成文本内容。它首先配置了OpenAI客户端连接到一个特定的API基础URL,随后定义了一个异步函数getChatResponse来与ChatGPT交互,传入模型名和提示信息,以获取AI生成的回复。脚本将一段关于泡茶的自然语言描述转换成步骤化的指令。
require('dotenv').config();
const OpenAI = require('openai');
const client = new OpenAI({
apiKey: process.env.OPENAI_KEY,
baseURL: 'https://api.chatanywhere.tech/v1/',
});
const getChatResponse = async function(model, prompt){//openAI 的聊天接口
const response = await client.chat.completions.create({
model: model,
messages:[{
role:"user" ,
content: prompt,
}]
})
return response.choices[0].message.content;
}
const main = async () => {
// AIGC 优势就是处理文本, 生成内容
const text = `
泡一杯茶很容易。首先,需要把水烧开。在等待期间,拿一个杯子
并把茶包放进去。 一旦水开了,就把他倒在茶包上。等待一会儿,
让茶叶浸泡,几分钟后,取出茶包。如果你愿意,可以加一些糖
或者牛奶调味。就这样,您可以享受一杯美味的茶了。
`
const prompt = `
您将获得由三个引号括起来的文本
如果它包含一系列的指令,需要按照以下格式重新编写这些指令。
第一步 - ...
第二步 - ...
...
第N步 - ...
如果文本中不包含一些系列的指令,则直接写"未提供步骤"
"""${text}"""
`
const result = await getChatResponse("gpt-3.5-turbo",prompt);
console.log(result);
};
main();
结果
结语
如同泡茶时那一缕升腾的热气,模板方法模式在软件开发中同样散发出智慧的光芒。它教会我们如何在不变的框架下拥抱变化,如何在繁复的代码中寻求简洁与优雅。在这个AI与传统编程技术不断融合的时代,理解并应用好模板方法模式,无疑是我们每位程序员“喝口茶”就能掌握的一项重要技能。泡一壶好茶,编一段好码,两者皆是匠心独具的艺术,都在追求着简单中的不凡,平凡中的卓越。