C++设计模式[4]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 csenior 的 blog

    模板与继承的本质区别之一是:模板:行为不依赖于类型。继承:行为依赖于类型。(effective c++ item 41) 事实上,在很多模式中都存在着可以用模板代替继承的情况,其根本原因就在于子类的行为是一致的

  四、示例代码

namespace designpattern_factorymethod
{
class product { /*...*/ } ;
class concreteproduct : public product { /*...*/ } ;

// class creator
class creator
{
public:
virtual product* createproduct() = 0 ;
void operate() ;
} ;

void creator::operate()
{
// ...
product *p = createproduct() ;
// ...
}

// class concretecreator
class concretecreator : public creator
{
public:
virtual product* createproduct() { return new concreteproduct() ; }
} ;
}

客户端代码:
{
using namespace designpattern_factorymethod ;
concretecreator p ;
p.operate() ;
}

    这里的createproduct其实也是一个template method。

  五、实例

  factory method的运用太广泛了,它经常运用在其它模式中,其实例举不胜数。
(1)

  mfc中的cdocument类就包含了类似于上图capplication中的三个函数。这里的createdocument就是一个factory method,因为它负责创建一个文档对象。

  (2)

  当一个类将它的一些职责委托给一个独立的类时,就产生了平行类层次。上图中figure和manipulator就是平行类层次,figure代表一些图形元素,如线、文字等,manipulator表示作用于这些图形元素的操作,如拖拉、移动、选中等。如果这些操作所需要的状态信息并不需要保存在figure中,那么把figure和manipulator分成两个类层次是个好主意。这里的createmanipulator就是一个factory method。



c++设计模式之composite
2002-08-06· · ··com集中营

  一、功能
  表示“部分-整体”关系,并使用户以一致的方式使用单个对象和组合对象。

  二、结构图

  上图中,也可以做些扩展,根据需要可以将leaf和composite做为抽象基类,从中派生出子类来。

  三、优缺点

  优点:对于composite模式,也许人们一开始的注意力会集中在它是如何实现组合对象的。但composite最重要之处在于用户并不关心是组合对象还是单个对象,用户将以统一的方式进行处理,所以基类应是从单个对象和组合对象中提出的公共接口。
  缺点:composite最大的问题在于不容易限制组合中的组件。

  四、实现

  有时需要限制组合中的组件,即希望一个composite只能有某些特定的leaf。这个问题我是用多继承和动态类型转换来解决的。假如组合对象composite1只能包含单个对象concreteleaf1,composite2可以包含单个对象concreteleaf1和concreteleaf2。如下图所示:

  上图中的类层次比较多,使用了abstractleaf1和abstractleaf2,但没使用abstractcomposite1和abstractcomposite2,这个并不重要,也可以把abstractleaf1和abstractleaf2去掉,这个并不重要,可以根据具体情况决定要不要。
简单的代码实现如下:

namespace designpattern_composite
{
class component
{
public:
virtual void operation() = 0 ;
virtual void add(component*) {}
} ;

class abstractcomponent1 : virtual public component {} ;

class abstractleaf1 : virtual public abstractcomponent1 {} ;

class composite1 : public abstractcomponent1
{
public:
virtual void operation() { /* do operation */ }
virtual void add(component*) ;
} ;
void composite1::add(component *p)
{
abstractcomponent1 *pc1 = dynamic_cast<abstractcomponent1*>(p) ;
if (pc1 == null) return ;
// do add operation
}

class abstractcomponent2 : virtual public component {} ;

class abstractleaf2 : virtual public abstractcomponent2 {} ;

class composite2 : public abstractcomponent2
{
public:
virtual void operation() { /* do operation */ }
virtual void add(component*) ;
} ;
void composite2::add(component *p)
{
abstractcomponent2 *pc2 = dynamic_cast<abstractcomponent2*>(p) ;
if (pc2 == null) return ;
// do add operation
}

class concreteleaf1 : public abstractleaf1
{
public:
virtual void operation() { /* do operation */ }
} ;

class concreteleaf2 : public abstractleaf1, public abstractleaf2
{
public:
virtual void operation() { /* do operation */ }
} ;
}

客户端代码:

using namespace designpattern_composite ;

component *pc1 = new concreteleaf1() ;
component *pc2 = new concreteleaf2() ;
component *pc3 = new composite1() ;
component *pc4 = new composite2() ;
pc3->add(pc1) ; // ok
pc3->add(pc2) ; // ok
pc3->add(pc3) ; // ok
pc3->add(pc4) ; // fail
pc4->add(pc1) ; // fail
pc4->add(pc2) ; // ok
pc4->add(pc3) ; // fail
pc4->add(pc4) ; // ok
}

  有两点需要注意,一是因为用了多继承,所以需要使用virtual inheritance。二是要用dynamic_cast来判断是否允许组合该组件。

  五、示例代码

namespace designpattern_composite
{
// class component
class component
{
public:
virtual void operation() = 0 ;
virtual void add(component*) {}
} ;

// class leaf
class leaf : public component
{
public:
virtual void operation() {}
} ;

// class composite
class composite : public component
{
public:
virtual void add(component *p) { _list.push_back(p) ; }
virtual void operation()
{
vector< component* >::const_iterator it ;
for (it = _list.begin(); it != _list.end(); it++)
(*it)->operation() ;
}
private:
vector< component* > _list ;
} ;
}

  六、实例

  (1)junit中就用的是composite模式。

本文关键:C++设计模式
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top