[设计模式] 1.Template Method(模板方法)

本文深入探讨模板方法模式,一种在软件工程中广泛应用的设计模式。它通过定义一个算法骨架,允许子类提供具体实现,从而达到代码复用和扩展性的目的。文章通过一个炒菜过程的例子,详细展示了如何在父类中定义固定步骤,同时让子类负责可变部分的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模板方法模式实现了分离可变和不变的部分,并把可变的部分封装起来。

在抽象类中定义一个总体框架,包含可变的和不可变的模块,然后将可变模块的实现延迟到子类中实现。使得子类可以在不改变框架结构的情况下,重新定义框架中某些模块的具体实现。

这也符合OO设计的几个重要原则:

封装变化 在这里指被抽向成虚函数的可变部分。

针对接口编程而不针对实现编程 框架定义在父类而不是具体的某个子类中。父类中的可变方法的实现不在父类,而是在各个子类。程序在运行时可以动态改变所指向的子类类型。

晚绑定代替早绑定

晚绑定和早绑定 

把函数体和函数调用相联系称为绑定。类中的一般的函数都是早绑定,也就是在调用的地方,已经把要调用的函数确定好了,调用的类就是定义它的类。

模板方法模式中,针对不可变部分使用的就是早绑定策略:父类指针不管指向哪个子类,调用到的永远都是父类中定义号的方法,也就是不可变

而针对可变部分则使用了晚绑定策略:将父类方法声明为virtual函数,调用该方法时,根据其指向的对象找vtpr指针,然后找vptr中找其具体的子类实现,也就是可变

应用实例

一个简单的例子,炒两道菜,第一步洗锅,第二部倒油,第三部放食材,第四部放调料,第五步翻炒装盘。其中一二五步是一样的操作,但是A菜和B菜所用的食材和调料是不一样的,所以定义一个抽象类将炒菜的过程抽象出来。

class Base {
public:
    //早绑定,不希望子类覆盖这个方法 
    void cookProcess()
    {
        //第一步:洗锅
        washPot();
        //第二步:倒油
        addOil();
        //第三步:放食材
        addVegetable();
        //第四步:倒调料
        addSauce();
        //第五步:翻炒装盘
        fry();
    }

protected:
    //决定结构里早绑定和晚绑定
    //第一步:洗锅是一样的,直接实现
    void washPot() {
        std::cout << "第一步:洗锅" << endl;
    }
    
    //第二步:倒油是一样的,直接实现
    void addOil() {
        std::cout << "第二步:倒油" << endl;
    }
    
    //第三步:放食材是不一样的,声明为虚方法,具体实现由子类进行覆盖
    virtual void  addVegetable() = 0;

	//第四步:倒调料是不一样的,声明为虚方法,具体实现由子类进行覆盖
	virtual void  addSauce() = 0;

	//第五步:翻炒装盘是一样的,所以直接实现
	void fry() {
		cout << "第五步:翻炒然后装盘" <<endl;
	}
};

针对不同的菜品实现不同的烹饪步骤。 

class cookA : public Base
{
protected:
	void  addVegetable() {
		cout << "第三步:炒A菜:放A菜食材" << endl;
	}
	
	void  addSauce() {
		cout << "第四步:炒A菜:放A菜的调料" << endl;
	}
};

class cookB : public  Base
{
protected:
	void  addVegetable() {
		cout << "第三步:炒B菜:放B菜食材" << endl;
	}
	
	void  addSauce() {
		cout << "第四步:炒B菜:放B菜的调料" << endl;
	}
};

在程序中改变炒菜父类的指向的子类对象即可实现不同菜品的烹饪。

int main()
{
	Base *p1 = new cookA;
	Base *p2 = new cookB;

	p1->cookProcess();
	p2->cookProcess();

	delete p1;
	delete p2;
	p1 = NULL;
	p2 = NULL;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值