(1) Composition(复合) 设计模式: have-a
以STL中的queue为例:
queue依托于双端队列deque来实现, 用UML图可表示为:
template <class T, class Sequence = deque<T> > class queue { ... protected: Sequence c; // 底层容器 public: // 以下完全利用 c 的操作函数完成 bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference front() { return c.front(); } reference back() { return c.back(); } // deque 是两端可进出,queue 是先进先出 void push(const value_type& x) { c.push_back(x); } void pop() { c.pop_front(); } };
像这样 一个对象依托于另一个对象来实现 为复合设计模式
在复合设计模式下:
构造由内而外:
Container::Container(……): Component() { …… } ;
(Container的构造函数首先调用Component的default构造函数 然后才执行自己
析构由外而内:Container::~Container(……) { …… ~Component() } ;
(Container 的析构函数首先执行自己,然后才调用 Component 的
析构函数。 )
这样的构造和析构的顺序很大程度保证了复合模式的稳定.
(2)Delegation(委托) 设计模式: (Composition by reference)
通过指针来引用另一个实现的类:
UML图如下:
// file String.hpp class StringRep; class String { public: String(); String(const char* s); String(const String& s); String &operator=(const String& s); ~String(); ... private: StringRep* rep; // point implementation };
// file String.cpp #include "String.hpp" namespace { class StringRep { friend class String; StringRep(const char* s); ~StringRep(); int count; char* rep; }; } String::String() { ... } ...
对比于前一种复合设计模式 它的好处在于不受被委托类的影响 被委托类即便修改了某个成员函数名, 也不需要在发起委托的类上修改.
同时 String类的多个对象可以共享rep指针指向的对象 减少了内存的占用
(3) Inheritance(继承) is-a
UML图如下:
struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; template<typename _Tp> struct _List_node : public _List_node_base // public继承 { _Tp _M_data; };
该模式即子类的对象包含有父类的成分: