模版方法模式
Template Method
组建协作: (晚绑定,运行时绑定)
Template Method (模板方法)
Strategy (策略模式)
Observer/ Event (观察者/事件)
面向对象设计模式是“好的面向对象设计”,所谓“好的面向对象设计”指是那些可以满足
“应对变化,提高复用”的设计 。现代软件设计的特征是“需求的频繁变化”。设计模式的要点是“寻找变化点,然后在变化
点处应用设计模式,从而来更好地应对需求的变化”.“什么时候、什么地点应用设计模式”
比“理解设计模式结构本身”更为重要。设计模式的应用不宜先入为主,一上来就使用设计模式是对设计模式的最大误用。没有
一步到位的设计模式。敏捷软件开发实践提倡的“Refactoring to Patterns”是目前普遍公认的最好的使用设计模式的方法。
动机 (Motivation)
- 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务
- 的整体结构同时实现。
定义
定义一个操作中的算法的骨架 (稳定),而将一些步骤延迟(变化)到子类中。Template
Method使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的
某些特定步骤。
——《设计模式》GoF
我们可以看到应用程序开发人员既要负责自己的任务,同时还需要负责程序的运行。这对
于应用程序开发人员来说负担太重。另一方面,再以后需求变化的时候,应用程序开发人员需要对所有的程序流程进行更改,这里的工作量是很大的。
1.1 制作汽车
class Car
{
public:
// 汽车启动
virtual void start() = 0;
// 汽车停止
virtual void stop() = 0;
// 汽车喇叭
virtual void alarm() = 0;
};
class BMW : public Car
{
public:
void start()
{
cout << "宝马车启动了..." << endl;
}
// 汽车停止
void stop()
{
cout << "宝马停止了" << endl;
}
// 汽车喇叭
void alarm()
{
cout << "宝马鸣笛,屌丝让道" << endl;
}
void run()
{
this->start();
this->alarm();
this->stop();
}
};
class Alto : public Car
{
public:
void start()
{
cout << "二手破烂Alto启动好久终于动了..." << endl;
}
// 汽车停止
void stop()
{
cout << "Alto靠脚刹停止了" << endl;
}
// 汽车喇叭
void alarm()
{
cout << "Alto鸣笛,发现喇叭坏了" << endl;
}
void run()
{
this->start();
this->alarm();
this->stop();
}
};
// ... 各种汽车型号
class Benz : public Car
{
// ...功能类似
void run()
{
this->start();
this->alarm();
this->stop();
}
};
我们可以清楚的看到,对于run的函数,我们好像是一直在复制粘贴,代码都是一样的。
当一段代码重复使用多次,我们就需要警惕了。这说明我们需要重构了。
注意 在软件开发过程中,如果相同的一段代码拷贝过两次,就需要对设计产生怀疑,
架构师要明确的说明为什么相同的逻辑要出现两次或更多次。
class Car
{
public:
// 汽车启动
virtual void start() = 0;
// 汽车停止
virtual void stop() = 0;
// 汽车喇叭
virtual void alarm() = 0;
void run()
{
start();
alarm();
stop();
}
};
class BMW : public Car
{
public:
void start()
{
cout << "宝马车启动了..." << endl;
}
// 汽车停止
void stop()
{
cout << "宝马停止了" << endl;
}
// 汽车喇叭
void alarm()
{
cout << "宝马鸣笛,屌丝让道" << endl;
}
};
class Alto : public Car
{
public:
void start()
{
cout << "二手破烂Alto启动好久终于动了..." << endl;
}
// 汽车停止
void stop()
{
cout << "Alto靠脚刹停止了" << endl;
}
// 汽车喇叭
void alarm()
{
cout << "Alto鸣笛,发现喇叭坏了" << endl;
}
};
// ... 各种汽车型号
class Benz : public Car
{
// ...功能类似
};
这样改了之后,代码确实能够重用。但是如果现在要生产一种汽车,这种汽车启动时不需要
鸣笛的(奇怪,竟然有这么奇怪的要求。难道做的是遥控车?),面对这种需求我们该怎么
处理呢?
class Car
{
public:
// 汽车启动
virtual void start() = 0;
// 汽车停止
virtual void stop() = 0;
// 汽车喇叭
virtual void alarm() = 0;
virtual bool isAlarm()
{
return true;
};
void run()
{
start();
if(isAlarm()){
alarm();
}
stop();
}
};
class Alto : public Car
{
public:
void start()
{
cout << "二手破烂Alto启动好久终于动了..." << endl;
}
// 汽车停止
void stop()
{
cout << "Alto靠脚刹停止了" << endl;
}
// 汽车喇叭
void alarm()
{
cout << "Alto鸣笛,发现喇叭坏了" << endl;
}
bool isAlarm() { return false; }
};

浙公网安备 33010602011771号