| c++设计模式之adapter |
二、结构图
(1)class adapter
(2)object adapter
三、实现
和其他很多模式一样,学习设计模式的重点是学习每种模式的思想,而不应拘泥于它的某种具体结构图和实现。因为模式是灵活的,其实现可以是千变万化的,只是所谓万变不离其宗。 在stl中大量运用了adapter模式,象function adapter、iterator adpter,它们与这里说的adapter结构并不一样,但思想是一样的。具体的介绍可到侯捷网站上找相关文章,他讲得非常好。四、示例代码
(1)class adapter|
namespace designpattern_adapter // class target // class adapter 客户端代码: |
(2)object adapter namespace designpattern_adapter
|
{ // class target // class adapter 客户端代码: |
六、实例
(1)stl中的class adapterstl中的adapter class包括:a.stack(对应的adaptee是deque)。b.queue(对应的adaptee是deque)。c.priority_queue(对应的adaptee是vector)。 下面是从vc中的< stack >拷出的stack的类定义:
|
template stack() explicit stack(const _container& _cont) bool empty() const size_type size() const value_type& top() const value_type& top() const void push(const value_type& _val) void pop() bool _eq(const stack<_ty, _container>& _right) const bool _lt(const stack<_ty, _container>& _right) const protected: |
关键之处在于_container c,stack所有的操作都转交给c去处理了。(这实际上就是前面所说的"object adapter",注意stl中的class adapter与上面所说的class adapter概念不完全一致)
stack的使用方法很简单,如下:
| { int ia[] = { 1,3,2,4 }; deque stack } |
(2)近日看了一篇文章“generic< programming >:简化异常安全代码”,原文出自http://www.cuj.com/experts/1812/alexandr.htm?topic=experts, 中文译文出自"c++ view第5期"。 文章绝对一流,作者给出的代码中也使用了adaptor模式,也有一定代表性。我将其问题一般化,概括出以下示例:
问题:假设有几个已有类,他们有某些共同的行为,但它们彼此间是独立的(没有共同的基类)。如:
|
class t1 class t2 // ... |
如何以统一的方式去调用这些行为呢?
解决方法1:很自然的会想到用模板,如:
| template <class t> void test(t t) { t.proc() ; } |
的确不错,但这只适用于简单的情况,有时情况是很复杂的,比如我们无法把类型放到模板参数中!
解决方法2:困难来自于这些类没有共同的基类,所以我们就创造一个基类,然后再adapt。
| // class iadaptor,抽象基类 class iadaptor { public: virtual void proc() = 0 ; } ; // class adaptor template <class t> class adaptor : public iadaptor, private t //实现继承 { public: virtual void proc() { t::proc() ; } } ; // 以统一方式调用函数proc,而不关心是t1、t2或其他什么类 void test(const std::auto_ptr { sp->proc() ; } 客户端代码: test(std::auto_ptr test(std::auto_ptr |
上例很简单,用方法一中的模板函数就可以很好地解决了。下面是一个略微复杂一点的例子,根据参数类型来创建适当的对象:
|
class t1 class t2 // class iadaptor,抽象基类 // class adaptor class test void proc() { sp->proc() ; } 客户端代码: test t2('c') ; |