一般来讲模式的主要获得方式不是一开始就有的 ,大部分情况都是重构获得的 ,
也就是 Refactoring to Patterns 。
好的面向对象的设计 就是指那些足以“应对变化 ,提高复用的设计”,现代软件设计特征是“需求的频繁变化”。
设计模式 就是寻找变化点,然后在变化点处应用设计模式,从而更好的去适应需求的变化,
“什么时候、什么地点应用设计模式”比“理解设计模式结构本身”更加重要。
设计模式的应用不是代码设计初期就一上来就去使用的,
这也是我作为初学者对设计模式最大的勿用。没有一步到位的设计模式。
敏捷软件开发 提倡使用重构的方式去得到一个良好的解决方案,从而得到设计模式。
碰巧就是那个模式。(这个可能就是武林高手的无形胜有形的原因吧)。
在面向对象的 语言里面 有一些关键词 在重构的过程中非常重要
静态-》动态
早绑定-》晚绑定
继承-》组合
编译时依赖-》运行时依赖
紧耦合-》松耦合
从封装变化的角度对 模板模式是 组件协作类。
现代软件专业分工之后第一个结果就是“框架与应用程序的划分”,
“组件协作”模式主要是通过晚期绑定的方式来实现框架与应用程序之间的松耦合。
典型的组件协作模式:
模板模式 Template Method
策略模式 Strategy
事件模式 Observer/Event
下面来具体谈谈 模板模式 :
动机: 在软件构建过程当中,对于某一项任务,它常常会有一个稳定的整体框架,但是各个子步骤会面临改变的需求,
或者由于固有的原因(比如框架和应用程序)而无法和任务的整体结构同时实现。必然会出现一个早,一个晚的关系。
下面通过代码来理解下前面这些内容。
伪代码1:
class Library{ //库开发人员
public :
void Step1();
void Step3();
void Step5();
};
class App{ // 应用程序开发人员
public :
void Step2();
void Step4();
};
int main(int argc, char *argv[])
{
// 应用程序开发人员
Library *lib = new Library;
App*app = new App;
/*这里的业务逻辑稳定*/
lib->Step1();
app->Step2();
lib->Step3();
app->Step4();
lib->Step5();
}
class Library{ //库开发人员
public :
void Step1();// 稳定的
void Step3();
void Step5();
virtual void Step2()=0; //变化的
virtual void Step4()=0;
virtual ~Library();
public:
void run(){//稳定的
Step1();
Step2(); //支持变化 虚函数调用
Step3();
Step4(); //支持变化 虚函数调用
Step5();
}
};
class App:public Library{ // 应用程序开发人员
public :
void Step2();
void Step4();
};
int main(int argc, char *argv[])
{
// 应用程序开发人员
Library *lib = new App;
lib->run();
}
在来看下第二段代码 这种叫做面向对象设计:
对比发现我们把相对稳定的主逻辑交给了早起开发库的人员来写了!这样看下来也没什么吗!不就是让应用程序人员更加省事,
库开发人员更加麻烦了而已。其实不然。我们来具体看下调用关系。
第一段代码 的调用程序的主流程(程序的业务逻辑) 是不是 后出现应用程序的去调用先出现的库程序。
也就是 早绑定。C语言非常主流的做法。
第二段代码 的调用程序的主流程 是不是 librar 通过虚函数 2 4 步骤 和run 方法去调用了晚出现App里面的方法才能实现这个程序主逻辑 ,
一个早出现的去调用晚出现的 就是晚绑定。
具有这样的调用关系的设计具体提升了什么呢?
首先复用性 如果一旦出现新的需求 需要修改我们之前注释过的变化的地方(step2 step4)是不是只需要继承过来重写就好。
其次也就是最只管的一个紧耦合变成了松耦合结构。
总结:
1.代码复用强
2.良好的可扩展性
3.反向控制,通过父类调用子类的操作,通过子类的扩展添加新的行为
缺点
当需求不停的变更,将会导致类的个数增加,系统更加庞大,设计也更加抽象。
回头来看下模板模式的gof中定义。
定义一个操作中的算法骨架(稳定 (run方法)),而将一些步骤延迟(变化)(通过虚函数和重写 step2 he step4) 到子类,(将变化给子类),
模板模式就是使子类可以不改变(复用)一个算法结构既可以重定义(override)改算法的某些特定的步骤
使用模板模式 就是run()是相对稳定的(1年一变化的和相对1个月一变化的就是相对稳定的 )。如果run()是使用模板模式的前提 也就是有个稳定的算法结构。
启发和思考:
设计模式就是在稳定和变化之中寻找隔离点,如果当前的程序全是变化,或者全是稳定的 就没有使用模式的必要,正常的软件结构都会存在稳定和变化。
模板模式 是一种非常基础的设计模式,在面向对象的系统当中有着大量的应用。它的机制非常简洁(多态)为了狠多框架提供灵活的扩展,是代码复用的基本实现结构。
它拥有反向控制结构 “不要调用我 ,让我来调用你”通过虚函数的方式来做成晚绑定。