??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲va久久久噜噜噜久久男同,成人国内精品久久久久一区,久久久久久精品无码人妻http://m.shnenglu.com/yehao/category/16561.htmlzh-cnFri, 06 May 2011 16:36:33 GMTFri, 06 May 2011 16:36:33 GMT60观察者模?设计模式http://m.shnenglu.com/yehao/articles/145337.html厚积薄发厚积薄发Fri, 29 Apr 2011 08:59:00 GMThttp://m.shnenglu.com/yehao/articles/145337.htmlhttp://m.shnenglu.com/yehao/comments/145337.htmlhttp://m.shnenglu.com/yehao/articles/145337.html#Feedback0http://m.shnenglu.com/yehao/comments/commentRss/145337.htmlhttp://m.shnenglu.com/yehao/services/trackbacks/145337.htmlhttp://m.shnenglu.com/unixfy/archive/2011/04/26/145077.html

Part of the red marker to add by YeHaoQOrder oneself to better understand.

观察者模?设计模式

来自于《大话设计模式?br>观察者模式:定义了一U一对多的依赖关p,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生时Q会通知所有观察者对象,使他们自动更新自己?br>
行ؓ型模式?br>
UML cdQ?br>
代码实现 C++Q?br>
  1 #include <iostream>
  2 #include <string>
  3 #include <list>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 class Subject;
  8 
  9 class Observer   //观察?/span>
 10 {
 11 protected:
 12     string name;
 13     Subject* sub;
 14 public:
 15     Observer(const string& n, Subject* s) : name(n), sub(s) {}
 16     virtual void Update() = 0;
 17 };
 18 
 19 class Subject   //被观察?br> 20 {
 21 protected:
 22     list<Observer*> observers;
 23     string action;
 24 public:
 25     virtual void Attach(Observer* ob) = 0;   //增加观察者对?br> 26     virtual void Detach(Observer* ob) = 0;   //U除观察者对?br> 27     virtual void Notify() = 0;
 28     virtual void setAction(const string& s) = 0;
 29     virtual string getAction() = 0;
 30 };
 31 
 32 class StockObserver : public Observer
 33 {
 34 public:
 35     StockObserver(const string& name, Subject* s) : Observer(name, s) {}
 36     virtual void Update()
 37     {
 38         cout << sub->getAction() << '\t' << name << " 关闭股票行情Ql工作!" << endl;
 39     }
 40 };
 41 
 42 class NBAObserver : public Observer
 43 {
 44 public:
 45     NBAObserver(const string& name, Subject* s) : Observer(name, s) {}
 46     virtual void Update()
 47     {
 48         cout << sub->getAction() << '\t' << name << " 关闭 NBAQl工作!" << endl;
 49     }
 50 };
 51 
 52 class Boss : public Subject
 53 {
 54 //private:
 55 //    list<Observer*> observers;
 56 //    string action;
 57 public:
 58     virtual void Attach(Observer* ob)
 59     {
 60         observers.push_back(ob);
 61     }
 62     virtual void Detach(Observer* ob)
 63     {
 64         list<Observer*>::iterator iter= find(observers.begin(), observers.end(), ob);
 65         if (iter != observers.end())
 66         {
 67             observers.erase(iter);
 68         }
 69     }
 70     virtual void Notify()
 71     {
 72         for (list<Observer*>::iterator iter = observers.begin(); iter != observers.end(); ++iter)
 73         {
 74             (*iter)->Update();
 75         }
 76     }
 77     virtual void setAction(const string& s)
 78     {
 79         action = s;
 80     }
 81     virtual string getAction()
 82     {
 83         return action;
 84     }
 85 };
 86 
 87 class Secretary : public Subject
 88 {
 89 //private:
 90 //    list<Observer*> observers;
 91 //    string action;
 92 public:
 93     virtual void Attach(Observer* ob)
 94     {
 95         observers.push_back(ob);
 96     }
 97     virtual void Detach(Observer* ob)
 98     {
 99         list<Observer*>::iterator iter = find(observers.begin(), observers.end(), ob);
100         if (iter != observers.end())
101         {
102             observers.erase(iter);
103         }
104     }
105     virtual void Notify()
106     {
107         for (list<Observer*>::iterator iter = observers.begin(); iter != observers.end(); ++iter)
108         {
109             (*iter)->Update();
110         }
111     }
112     virtual void setAction(const string& s)
113     {
114         action = s;
115     }
116     virtual string getAction()
117     {
118         return action;
119     }
120 };
121 
122 
123 
124 int main()
125 {
126     Boss* huhansan = new Boss;
127     StockObserver* so = new StockObserver("abc", huhansan);
128     NBAObserver*   no = new NBAObserver("xyz", huhansan);
129 
130     huhansan->Attach(so);
131     huhansan->Attach(no);
132     huhansan->setAction("我胡汉三又回来了Q?/span>");
133     huhansan->Notify();
134 
135     huhansan->Detach(no);
136     huhansan->setAction("开会!");
137     huhansan->Notify();
138 
139     delete huhansan;
140 
141     Secretary* s = new Secretary;
142     s->Attach(no);
143     s->Attach(so);
144     s->setAction("老板来了Q?/span>");
145     cout << s->getAction() << endl;
146     s->Notify();
147 
148     delete so;
149     delete no;
150     delete s;
151     
152     return 0;
153 }



厚积薄发 2011-04-29 16:59 发表评论
]]>
C++设计模式(转蝲)http://m.shnenglu.com/yehao/articles/144137.html厚积薄发厚积薄发Wed, 13 Apr 2011 09:47:00 GMThttp://m.shnenglu.com/yehao/articles/144137.htmlhttp://m.shnenglu.com/yehao/comments/144137.htmlhttp://m.shnenglu.com/yehao/articles/144137.html#Feedback0http://m.shnenglu.com/yehao/comments/commentRss/144137.htmlhttp://m.shnenglu.com/yehao/services/trackbacks/144137.html本文来自CSDN博客Q{载请标明出处Q?/span>http://blog.csdn.net/i_like_cpp/archive/2004/11/29/197760.aspx


一、功?/strong>

 

  一个类的接口{换成客户希望的另外一个接口,解决两个已有接口之间不匹配的问题。Adapter模式使得原本׃接口不兼容而不能一起工作的那些cd以一起工作?

  二、结构图

  (1)class adapter

  (2)object adapter

三、实?/p>

  和其他很多模式一P学习设计模式的重Ҏ学习每种模式的思想Q而不应拘泥于它的某种具体l构囑֒实现。因为模式是灉|的,其实现可以是千变万化的,只是所谓万变不d宗?在STL中大量运用了Adapter模式Q象function adapter、iterator adpterQ它们与q里说的adapterl构q不一P但思想是一L。具体的介绍可到侯捷|站上找相关文章Q他讲得非常好?
  四、示例代?/p>

  (1)class adapter

namespace DesignPattern_Adapter
{
// class Adaptee
class Adaptee
{
public:
void SpecialRequest() {}
} ;

// class Target
class Target
{
public:
virtual void Request() = 0 ;
} ;

// class Adapter
class Adapter : public Target, private Adaptee
{
public:
virtual void Request() { SpecialRequest() ; }
} ;
}

客户端代码:
{
using namespace DesignPattern_Adapter ;
Target *p = new Adapter() ;
p->Request() ; //实际上调用的是Adaptee::SpecialRequest()
}
 

(2)object adapter namespace DesignPattern_Adapter


{
// class Adaptee
class Adaptee
{
public:
void SpecialRequest() {}
} ;

// class Target
class Target
{
public:
virtual void Request() = 0 ;
} ;

// class Adapter
class Adapter : public Target
{
public:
virtual void Request() { _adaptee.SpecialRequest() ; }
private:
Adaptee _adaptee ;
} ;
}

客户端代码:
{
using namespace DesignPattern_Adapter ;
Target *p = new Adapter() ;
p->Request() ; //实际上调用的是Adaptee::SpecialRequest()
}
 

  六、实?/p>

  (1)STL中的Class Adapter

  STL中的Adapter Class包括Qa.stack(对应的adaptee是deque)。b.queue(对应的adaptee是deque)。c.priority_queue(对应的adaptee是vector)?下面是从VC中的< stack >拷出的stack的类定义Q?

templateclass _Container = deque<_Ty> >
class stack
{ // LIFO queue implemented with a container
public:
typedef _Container container_type;
typedef typename _Container::value_type value_type;
typedef typename _Container::size_type size_type;

stack()
: c()
{ // construct with empty container
}

explicit stack(const _Container& _Cont)
: c(_Cont)
{ // construct by copying specified container
}

bool empty() const
{ // test if stack is empty
return (c.empty());
}

size_type size() const
{ // test length of stack
return (c.size());
}

value_type& top()
{ // return last element of mutable stack
return (c.back());
}

const value_type& top() const
{ // return last element of nonmutable stack
return (c.back());
}

void push(const value_type& _Val)
{ // insert element at end
c.push_back(_Val);
}

void pop()
{ // erase last element
c.pop_back();
}

bool _Eq(const stack<_Ty, _Container>& _Right) const
{ // test for stack equality
return (c == _Right.c);
}

bool _Lt(const stack<_Ty, _Container>& _Right) const
{ // test if this < _Right for stacks
return (c < _Right.c);
}

protected:
_Container c; // the underlying container
};
 

  关键之处在于_Container cQstack所有的操作都{交给cd理了?q实际上是前面所说的"object adapter"Q注意STL中的class adapter与上面所说的class adapter概念不完全一?
stack的用方法很单,如下Q?

 

{
int ia[] = { 1,3,2,4 };
deque id(ia, ia+4);
stack is(id);
}

  (2)q日看了一文?#8220;Generic< Programming >Q简化异常安全代?#8221;Q原文出?a C++ ViewW???文章l对一,作者给出的代码中也使用了Adaptor模式Q也有一定代表性。我其问题一般化Q概括出以下CZQ?

  问题Q假设有几个已有c,他们有某些共同的行ؓQ但它们彼此间是独立?没有共同的基c?。如Q?

class T1
{
public:
void Proc() {}
} ;

class T2
{
public:
void Proc() {}
} ;

// ...
 


  如何以统一的方式去调用q些行ؓ呢?

  解决Ҏ1Q很自然的会惛_用模板,如:

template <class T>
void Test(T t)
{
t.Proc() ;


  的确不错Q但q只适用于简单的情况Q有时情冉|很复杂的Q比如我们无法把cd攑ֈ模板参数中!

  解决Ҏ2Q困难来自于q些cL有共同的基类Q所以我们就创造一个基c,然后再Adapt?

// class IAdaptorQ抽象基c?br>class IAdaptor
{
public:
virtual void Proc() = 0 ;
} ;
// class Adaptor
template <class T>
class Adaptor : public IAdaptor, private T //实现l承
{
public:
virtual void Proc() { T::Proc() ; }
} ;
// 以统一方式调用函数ProcQ而不兛_是T1、T2或其他什么类
void Test(const std::auto_ptr& sp)
{
sp->Proc() ;
}
客户端代码:
Test(std::auto_ptr(new Adaptor)) ;
Test(std::auto_ptr(new Adaptor)) ; 


  上例很简单,用方法一中的模板函数可以很好地解决了。下面是一个略微复杂一点的例子Q根据参数类型来创徏适当的对象:

 

class T1
{
public:
T1(int) { /*...*/ }
void Proc() { /*...*/ }
} ;

class T2
{
public:
T2(char) { /*...*/ }
void Proc() { /*...*/ }
} ;

// class IAdaptorQ抽象基c?br>class IAdaptor
{
public:
virtual void Proc() = 0 ;
} ;

// class Adaptor
template
class Adaptor : public IAdaptor, private T //实现l承
{
public:
Adaptor(int n) : T(n) {}
Adaptor(char c) : T(c) {}
virtual void Proc() { T::Proc() ; }
} ;

class Test
{
public:
Test(int n) : sp(new Adaptor(n)) {}
Test(char c) : sp(new Adaptor(c)) {}

void Proc() { sp->Proc() ; }
private:
std::auto_ptr sp ;
} ;

客户端代码:
Test t1(10) ;
t1.Proc() ;

Test t2('c') ;
t2.Proc() ;
 

  上面是示例而非实例Q你也许更愿意看看它实际的运用。去下蝲作者所写的代码Q好好欣赏一下吧?br>
C++设计模式之Abstract Factory
2002-07-23· · ··COM集中?br>
  一、功?/strong>
  提供一个创Zpd相关或相互依赖对象的接口Q而无需指定它们具体的类?

  二、结构图

  cd最基本的结构示意图如下Q?

 

  在实际应用中Q类厂模式可以扩充到很复杂的情况Q如下图所C:

 


三、优~点

  优点Q?1)装创徏q程。客户不用知道类厂是如何创徏cd例的Q类厂封闭了所有创建的l节。这样可选择不同的创建方法,增加了灵zL?(2)客户与具体c隔,提高了各自的可重用性?
  ~点QFactorycdơ与具体cdơ通常是^行的(即一一对应?。增加一个具体类Q一般也要相应地增加一个factoryc,增加了系l复杂度?

  四、实?/p>

  (1)Abstract FactorycM通常是一lFactory Method的集合。个ZFactory Method模式没有本质区别?

  (2)通常可以把工厂作为单件?
  五、示例代?/p>

namespace DesignPattern_AbstractFactory

{

  class AbstractProductA {}; // Product A

  class ProductA1 : public AbstractProductA {};

  class ProductA2 : public AbstractProductA {};

  class AbstractProductB {}; // Product B
  class ProductB1 : public AbstractProductB {};
  class ProductB2 : public AbstractProductB {};
  class AbstractFactory
  {
  public:
    virtual AbstractProductA* CreateProductA() = 0 ;// 创徏ProductA
    virtual AbstractProductB* CreateProductB() = 0 ;// 创徏ProductB
} ;
  class ConcreteFactory1 : public AbstractFactory
  {
  public:
    virtual AbstractProductA* CreateProductA() { return new ProductA1() ; }
    virtual AbstractProductB* CreateProductB() { return new ProductB1() ; }
    static ConcreteFactory1* Instance() { static ConcreteFactory1 instance ; return &instance ; }   
protected:
    ConcreteFactory1() {}
  private:
    ConcreteFactory1(const ConcreteFactory1&) ;
    ConcreteFactory1& operator=(const ConcreteFactory1&) ;
  } ;
  class ConcreteFactory2 : public AbstractFactory
  {
  public:
    virtual AbstractProductA* CreateProductA() { return new ProductA2() ; }
    virtual AbstractProductB* CreateProductB() { return new ProductB2() ; }
    static ConcreteFactory2* Instance() { static ConcreteFactory2 instance ; return &instance ; }
  protected:
    ConcreteFactory2() {}
  private:
    ConcreteFactory2(const ConcreteFactory2&) ;
    ConcreteFactory2& operator=(const ConcreteFactory2&) ;
  } ;
}

客户端代码:

{
  using namespace DesignPattern_AbstractFactory ;
  // W一U创建方?/p>

  AbstractFactory *pFactory = ConcreteFactory1::Instance() ;
  AbstractProductA *pProductA = pFactory->CreateProductA() ;
  AbstractProductB *pProductB = pFactory->CreateProductB() ;

  // W二U创建方?br>  pFactory = ConcreteFactory2::Instance() ;
  pProductA = pFactory->CreateProductA() ;
  pProductB = pFactory->CreateProductB() ;
}

  六、实?/p>

  最早知道类厂的概念是在COM中,但当时也没想到这是如此重要的一U模式,在许多其他模式中都可以用到类厂模式?COM中不能直接创建组Ӟq也是由COM的一个特性决定的Q即客户不知道要创徏的组件的cd?/p>

C++设计模式之Singleton
2002-07-26· · ··COM集中?

  一、功?

  保证一个类仅有一个实例?

  二、结构图



三、优~点

  Singleton模式是做?全局变量"的替代品出现的。所以它h全局变量的特点:全局可见、诏I应用程序的整个生命期,它也h全局变量不具备的性质Q同cd的对象实例只可能有一个?

  四、实?/p>

  教科书上的Singleton定义如下Q?


class Singleton
{
public:
static Singleton* Instance() ;
protected:
Singleton() {}
private:
static Singleton *_instance ;
Singleton(const Singleton&) ;
Singleton& operator=(const Singleton&) ;
} ;

Singleton* Singleton::_instance = NULL ;

Singleton* Singleton::Instance()
{
(_instance == NULL) ? _instance = new Singleton() : 0 ; //lazy initialization
return _instance ;
}
 

  (1)因ؓq回的是指针Qؓ防止用户调用delete函数Q可把static Singleton *_instanceQ改为在Instance()中定义static Singleton _instance。这h然更安全Q同时也hlazy initialization的特?即第一ơ访问时才创??

  (2)假设需要从Singletonz子类Q而子cM需要有同样的性质Q既只能创徏一个实例。我觉得Q这很难办。根本原因在于Instance()函数不是虚函敎ͼ不具有多态的性质。一U常用方法是把Instance()函数Ud子类中,q时只能用static Singleton *_instanceQ而不能用static Singleton _instance了,除非把_instance也要Ud子类Q无论怎么做都不优雅。另一U方法是用模ѝ具体用什么方法,只能Ҏ实际情况权衡?

  五、示例代?/p>

  (1)没子cȝ情况

namespace DesignPattern_Singleton
{

class Singleton
{
public:
static Singleton* Instance() { static Singleton _instance ; return &_instance ; }
protected:
Singleton() {}
private:
Singleton(const Singleton&) ;
Singleton& operator=(const Singleton&) ;
} ;
}

客户端代码:
{
using namespace DesignPattern_Singleton ;
Singleton *p = Singleton::Instance() ;
......
}
 

  (2)有子cȝ情况


Ҏ一Q?br>namespace DesignPattern_Singleton
{
// class Singleton
class Singleton
{
protected:
Singleton() {}
static Singleton *_instance ;
private:
Singleton(const Singleton&) ;
Singleton& operator=(const Singleton&) ;
} ;
Singleton* Singleton::_instance = NULL ;

// class ConcreteSingleton
class ConcreteSingleton : public Singleton
{
public:
static Singleton* Instance() ;
protected:
ConcreteSingleton() {}
} ;

Singleton* ConcreteSingleton::Instance()
{
(_instance == NULL) ? _instance = new ConcreteSingleton() : 0 ;
return _instance ;
}
}

客户端代码:
{
using namespace DesignPattern_Singleton ;
Singleton *p = ConcreteSingleton::Instance() ;
}

Ҏ二:
namespace DesignPattern_Singleton
{
// class Singleton
class Singleton
{
protected:
Singleton() {}
private:
Singleton(const Singleton&) ;
Singleton& operator=(const Singleton&) ;
} ;

// class ConcreteSingleton
class ConcreteSingleton : public Singleton
{
public:
static Singleton* Instance() { static ConcreteSingleton _instance ; return &_instance ; }
protected:
ConcreteSingleton() {}
} ;
}

客户端代码:
{
using namespace DesignPattern_Singleton ;
Singleton *p = ConcreteSingleton::Instance() ;
}

Ҏ三:
namespace DesignPattern_Singleton
{
template < class T >
class Singleton
{
public:
static T* Instance() { static T _instance ; return &_instance ; }
protected:
Singleton() {}
private:
Singleton(const Singleton &) ;
Singleton& operator=(const Singleton&) ;
} ;

class ConcreteSingleton : public Singleton< ConcreteSingleton > {} ;
}

客户端代?br>{
using namespace DesignPattern_Singleton ;

ConcreteSingleton *p = ConcreteSingleton::Instance() ;
}
 
 
C++模式开发之Bridge
2002-07-29· · ··COM集中?

  一、功?/strong>
  抽象部分与它的实现部分分离Q它们都可以独立地变化?

  二、结构图


三、示例代?
namespace DesignPattern_Bridge
{
// class Implementor
class Implementor
{
public:
virtual void OperationImp() = 0 ;
} ;

// class ConcreteImplementorA
class ConcreteImplementorA : public Implementor
{
public:
virtual void OperationImp() {}
} ;

// class ConcreteImplementorB
class ConcreteImplementorB : public Implementor
{
public:
virtual void OperationImp() {}
} ;

// class Abstraction
class Abstraction
{
public:
void Operation(Implementor* imp) { assert(imp) ; imp->OperationImp() ; }
} ;
}

客户端代码:
{
using namespace DesignPattern_Bridge ;

Abstraction obj ;
Implementor *impa = new ConcreteImplementorA() ;
Implementor *impb = new ConcreteImplementorB() ;
obj.Operation(impa) ; //W一U实现方?br>obj.Operation(impb) ; //W二U实现方?br>}
 


  四、实?/p>

  (1)创徏可以在X Window System和IBM的Presentation Managerpȝ中都可以使用的窗口?书上的例?


Bridge的魅力在于抽象和实现之间是松散的关系Q它们之间可以进行随意组合。如上图中,有IconWindow+XWindowImp、TransientWindow+XWindowImp、IconWindow+PMWindowImp、TransientWindow+PMWindowImp四种l合?br>
C++模式设计之Builder
2002-07-30· · ··COM集中?

  一、功?/strong>

  一个复杂对象的构徏与它的表C分,使得同样的构E可?strong>创徏不同的表C?/strong>?

  二、结构图

各类之间的交互关pd下图所C:


三、示例代?

namespace DesignPattern_Builder
{
class Product1 { /*...*/ } ;
class Product2 { /*...*/ } ;

// class Builder
class Builder //抽象基类
{
public:
virtual void BuilderPartA() {} //提供~省实现
virtual void BuilderPartB() {}
virtual void BuilderPartC() {}
protected:
Builder() {}
} ;

// class ConcreteBuilder1
class ConcreteBuilder1 : public Builder //创徏Product1
{
public:
ConcreteBuilder1() : _product(NULL) {}

virtual void BuilderPartA() { /*...*/ }
virtual void BuilderPartB() { /*...*/ }
virtual void BuilderPartC() { /*...*/ }

virtual Product1* GetProduct1() { return _product ; } //q回创徏的Product1对象
private:
Product1 *_product ;
} ;

// class ConcreteBuilder2
class ConcreteBuilder2 : public Builder //创徏Product2
{
public:
ConcreteBuilder2() : _product(NULL) {}

virtual void BuilderPartA() { /*...*/ }
virtual void BuilderPartB() { /*...*/ }
virtual void BuilderPartC() { /*...*/ }

virtual Product2* GetProduct2() { return _product ; } //q回创徏的Product2对象
private:
Product2 *_product ;
} ;

// class Director
class Director
{
public:
//创徏对象(Directorq不知道具体创徏出来的对象是什么样的,只有调用该函数的client知道)
void Construct(Builder *builder)
{
builder->BuilderPartA() ;
builder->BuilderPartB() ;
builder->BuilderPartC() ;
}
} ;
}

客户端代码:
{
using namespace DesignPattern_Builder ;

Director director ;

// 创徏W一U对?br>ConcreteBuilder1 *pBuilder1 = new ConcreteBuilder1() ;
director.Construct(pBuilder1) ;
Product1 *product1 = pBuilder1->GetProduct1() ;

// 创徏W二U对?br>ConcreteBuilder2 *pBuilder2 = new ConcreteBuilder2() ;
director.Construct(pBuilder2) ;
Product2 *product2 = pBuilder2->GetProduct2() ;
}
 


  四、实?/p>

  (1)例子一。如下图所C:



上图的功能是是把一个RTF文g转换为多U正文格式。RTFReaderq行语法分析Q然后将所有的token串逐一转换。可见builder是一步步地把各个部分l装Z个整体。它闭了组装的ҎQ组装出来的对象也大相径庭?br>
C++设计模式之Prototype
2002-08-01· · ··COM集中?

  一、功?/strong>

  用原型实例指定创建对象的U类Qƈ且通过q些原型创徏新的对象?



  二、结构图


三、优~点

  优点Q复制自w。客户不知道需要对象的实际cdQ只需知道它的抽象基类卛_?xl承树的情况)

  ~点Q必d有一个对象实?卛_?才能clone?

  四、示例代?/p>

namespace DesignPattern_Prototype
{
// class Prototype
class Prototype //抽象基类
{
public:
virtual Prototype* Clone() = 0 ;
} ;

// class ConcretePrototype1
class ConcretePrototype1 : public Prototype
{
public:
virtual Prototype* Clone()
{
ConcretePrototype1 *p = new ConcretePrototype1() ;
*p = *this ; //复制对象
return p ;
}
} ;

// class ConcretePrototype2
class ConcretePrototype2 : public Prototype
{
public:
virtual Prototype* Clone()
{
ConcretePrototype2 *p = new ConcretePrototype2() ;
*p = *this ; //复制对象
return p ;
}
} ;
}

客户端代码:
{
using namespace DesignPattern_Prototype ;

ConcretePrototype1 *obj1 = new ConcretePrototype1() ;//原型对象1
ConcretePrototype2 *obj2 = new ConcretePrototype2() ;//原型对象2

Prototype *newobj1 = obj1->Clone() ;//克隆对象1
Prototype *newobj2 = obj2->Clone() ;//克隆对象2

//使用复制出的对象newobj1和newobj2
}
 

  五、实?/p>

     在一个图形编辑器中,每一个图形元素,如线、圆、文字等都应该支持拷贝操作,即点中图形,按下Ctrl+CQ再按下Ctrl+V后就会复制一个新的图形。显然这是一Uclone操作。所以在每个从Graphicz出的囑Ş子类都应q用Prototype模式Q加上Clone操作?br> 

C++设计模式之Factory Method
2002-08-05· · ··COM集中?

  一、功?/strong>

  定义一个用于创建对象的接口Q让子类军_实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类?

  二、结构图


三、实?/p>

(1)在某些情况下Q比如仅仅ؓ了创建适当的Product对象而派生新的Creator子类Qƈ且创Z同Product的方法一致时Q可以考虑用模板代替ѝ如Q?

class Creator
{
public:
virtual Product* CreateProduct() = 0 ;
};

template < class ConcreteProduct >
class ConcreteCreator: public Creator
{
public:
virtual Product* CreateProduct() { return new ConcreteProduct() ; }
};

    模板与承的本质区别之一是:模板Q行Z依赖于类型。承:行ؓ依赖于类型?Effective C++ Item 41) 事实上,在很多模式中都存在着可以用模板代替承的情况Q其Ҏ原因在于子cȝ行ؓ是一致的?

  四、示例代?/p>

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() ;
}
 

    q里的CreateProduct其实也是一个Template Method?

  五、实?/p>

  Factory Method的运用太q泛了,它经常运用在其它模式中,其实例D不胜数?
(1)


MFC中的CDocumentcd包含了类g上图CApplication中的三个函数。这里的CreateDocument是一个factory methodQ因为它负责创徏一个文对象?

  (2)


当一个类它的一些职责委托给一个独立的cLQ就产生?strong>qcd?/strong>。上图中Figure和Manipulator是qcdơ,Figure代表一些图形元素,如线、文字等QManipulator表示作用于这些图形元素的操作Q如拖拉、移动、选中{。如果这些操作所需要的状态信息ƈ不需要保存在Figure中,那么把Figure和Manipulator分成两个cdơ是个好L。这里的CreateManipulator是一个factory method?br>
C++设计模式之Composite
2002-08-06· · ··COM集中?

  一、功?/strong>
  表示“部分-整体”关系Qƈ使用户以一致的方式使用单个对象和组合对象?

  二、结构图


上图中,也可以做些扩展,Ҏ需要可以将Leaf和Composite做ؓ抽象基类Q从中派生出子类来?

  三、优~点

  优点Q对于Composite模式Q也思h们一开始的注意力会集中在它是如何实现组合对象的。但Composite最重要之处在于用户q不兛_是组合对象还是单个对象,用户以l一的方式进行处理,所以基cd是从单个对象和组合对象中提出的公共接口?
  ~点QComposite最大的问题在于不容易限制组合中的组件?

  四、实?/p>

  有时需要限制组合中的组Ӟ卛_望一个Composite只能有某些特定的Leaf。这个问题我是用多承和动态类型{换来解决的。假如组合对象Composite1只能包含单个对象ConcreteLeaf1QComposite2可以包含单个对象ConcreteLeaf1和ConcreteLeaf2。如下图所C:


上图中的cdơ比较多Q用了AbstractLeaf1和AbstractLeaf2Q但没用AbstractComposite1和AbstractComposite2Q这个ƈ不重要,也可以把AbstractLeaf1和AbstractLeaf2LQ这个ƈ不重要,可以Ҏ具体情况军_要不要?
单的代码实现如下Q?

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_castQABSTRACTCOMPONENT1*Q?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_castQABSTRACTCOMPONENT2*>(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 */ }
} ;
}

客户端代码:
?br>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
}
 


  有两炚w要注意,一是因为用了多l承Q所以需要用virtual inheritance。二是要用dynamic_cast来判断是否允许组合该lg?/p>

  五、示例代?/p>

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 ;
} ;
}
 

  六、实?/p>

  (1)JUnit中就用的是Composite模式?

 



厚积薄发 2011-04-13 17:47 发表评论
]]>
þ͵wcŮ| ޹˾þһþ| þҹ³˿Ƭϼ | ŷþþƷһcƬƬ| ھƷ˾þþþavһ | þþ91Ʒһ| 鶹AV뾫Ʒþ| 99þĻ| þþþþavѿƬ| þþƷav鶹ͼƬ| þþþùƷŮӰԺ| þwww˳ɾƷ㽶| ޾Ʒþþþþò| ٸ޾þþþþ| þþþùɫAVѿͼƬ| ٸ޾þþþþ| ƷþþĻ| AVþþƷݺݰ˳| ۺɫۺϾþۺ| Ů޾Ʒþþۺ| ۺɫۺϾþۺ| ŷþþþƷ| 77777ҹþö| þþþƷר| þþþAVۺ| 66þôýվȸ| þ뾫Ʒһ| Ʒ99þþþþլ | ľþþƷww16| þֻоƷƵ99| þƵۿ| ھƷþþþ| ޾Ʒtvþþþþþþ| ٸþĻ | þĻƷһ| ˾þþƷһ| þù޾Ʒ| þˬˬƬAV| ޾Ʒþþþȥq| ھƷþۺ88 | þþþavרˮ|