// // // // // // // // //
///2013.1.22
// // // // // // // // //
老师布置了一项作业,
——制作一个小板凳。
被誉为天才的舒马赫同学很快的完成了一个又漂亮,又精致的艺术板凳。
而一直被班上同学所嘲笑的笨笨的爱因斯坦同学磨磨蹭蹭地,
转天早上才交上一个形状奇异而古怪的"小板凳"。
这是小时候看到的一篇励志故事。
不管寓意如何,
但是它正好可以适合我们今天所要讲的结构型设计模式:Bridge。
【核心】将抽象部分与它内部所组合的部分分离,使得它们可以独立地变化。
这是我将GoF的官方解释稍微变更一下所得的结论。
来看一下UML图:
其中Abstraction就是上述的抽象部分,
内部所组合的就是AbstractionImp。
实现的方法十分简单,
Abstraction内部组合一个(或多个)同学,
然后下达一个命令(例如老师布置制作小板凳作业),
而具体的实现,
就看传到Abstraction构造函数里面的是舒马赫还是爱因斯坦同学了。
这是一个非常实用的模式。
使用组合代替继承,
很好地代表了设计模式的核心思想:low coupling,high cohension.
代码实例:
【大致思路】
虚基类Student类的两个派生类分别为爱因斯坦与舒马赫,他们都拥有父类的方法:submitHomework.而另一个类Bridge类中聚合了一个Student接口,
可以通过控制在构造器中传入的实例,来显示不同同学提交的不同的作业。
Student.h
#ifndef _STUDENT_H_ #define _STUDENT_H_ class Student { protected: char* name; public : Student(){} Student(const Student& stu){} ~Student(){} //Interface virtual void submitHomework() = 0; }; class Einstein : public Student { protected: char* name; public: Einstein(); Einstein(const Einstein& e){}; ~Einstein(){}; void submitHomework(); }; class Schumacher : public Student { protected: char* name; public: Schumacher(); Schumacher(const Schumacher& e){}; ~Schumacher(){}; void submitHomework(); }; #endif
Student.cpp
#include "Student.h" #include<iostream> Einstein::Einstein() { name = "Einstein"; } void Einstein::submitHomework() { std::cout<<name<<"'s homework: "<<"Bad Bandeng"<<std::endl; } Schumacher::Schumacher() { name = "Schumacher"; } void Schumacher::submitHomework() { std::cout<<name<<"'s homework: "<<"Good Bandeng"<<std::endl; }
Bridge.h
#ifndef _TEACHER_H_ #define _TEACHER_H_ #include"Student.h" class Bridge { private: Student* student; public: Bridge(Student* stu); void getStudentsHomework(); }; #endif
Bridge.cpp
#include"Bridge.h" Bridge::Bridge(Student* stu) { this->student = stu; } void Bridge::getStudentsHomework() { this->student->submitHomework(); }
main.cpp
#include"Bridge.h" int main() { Student* einstein = new Einstein(); Student* schumacher = new Schumacher(); Bridge* bridge_1 = new Bridge(einstein); Bridge* bridge_2 = new Bridge(schumacher); bridge_1->getStudentsHomework(); bridge_2->getStudentsHomework(); return 0; }
输出结果:
【注意事项】
可以看到,
代码最关键的部分在于Bridge的构造函数。
最后做出什么产品与传入的制作者有关。
顺便一提,
这个模式大多用来适配软件的不同版本(凭借共同的接口)。
跑一点题,
我们每个人都有自己擅长的方向,
每个人都有属于自己的光芒。
因此没有必要为了自己不如其他人如何如何而烦恼。
抬起头来,
去寻找天空中属于自己的那一颗星。
发明相对论的不是舒马赫,
而且也别忘了,
爱因斯坦还有他的小板凳呢。
Just to be yourself.
And——
Keep moving.