锘??xml version="1.0" encoding="utf-8" standalone="yes"?>少妇人妻综合久久中文字幕,伊人久久大香线蕉综合影院首页 ,午夜精品久久久久久99热http://www.shnenglu.com/michaelgao/category/8288.htmlzh-cnWed, 07 Jan 2009 01:25:19 GMTWed, 07 Jan 2009 01:25:19 GMT60C++瀹岀編瀹炵幇Singleton妯″紡http://www.shnenglu.com/michaelgao/archive/2009/01/06/71345.htmlmicheal's techmicheal's techTue, 06 Jan 2009 08:06:00 GMThttp://www.shnenglu.com/michaelgao/archive/2009/01/06/71345.htmlhttp://www.shnenglu.com/michaelgao/comments/71345.htmlhttp://www.shnenglu.com/michaelgao/archive/2009/01/06/71345.html#Feedback2http://www.shnenglu.com/michaelgao/comments/commentRss/71345.htmlhttp://www.shnenglu.com/michaelgao/services/trackbacks/71345.html
澶у閮界煡閬擄紝鍦ㄧ敤C++鏉ュ疄鐜癝ingleton妯″紡鐨勬椂鍊欓氬父鎶婃瀯閫犲嚱鏁板0鏄庝負縐佹湁鐨勬垨鑰呬繚鎶ょ殑銆傚悓鏃跺0鏄庝竴涓叕鏈夌殑闈欐佺殑浼瀯閫犲嚱鏁幫紝閫氳繃瀹冩潵璋冪敤鐪熸鐨勬瀯閫犲嚱鏁般傚湪瀹炵幇榪欎釜浼瀯閫犲嚱鏁扮殑鏃跺欓氬父鏈変袱縐嶆柟寮忥細  
  class   Singleton;  
   
  static   Singleton&   Singleton:;fakeSingleton()  
  {  
          static   Singleton   s;  
          return   s;  
  }  
  絎簩縐嶆柟寮?  
  class   Singleton{  
  public:  
  static   Singleton*   fakeSingleton();  
  ...  
  private:  
  Singleton();  
  static   Singleton   *   _instance;  
  }  
  Singleton*   Singleton::fakesinketon()  
  {  
        if(   _instance==NULL)  
                  _instance=new   Singleton();  
          return   _instance;  
  }  
  瀵逛簬榪欎袱縐嶆柟寮忔垜瑙夊緱絎竴縐嶆洿濂戒竴浜涳紝鐞嗙敱鏄紝濡傛灉鏈変袱涓互涓婄殑綰跨▼鍚屾椂璁塊棶浼瀯閫犲嚱鏁扮殑鏃跺欐湁鍙兘鍚屾椂榪涘叆if   鎺у埗鍧楋紝榪欐牱灝辨湁鍙兘浜х敓涓や釜瀹炰緥錛侊紒鍥犳蹇呴』閲囩敤鐗規畩鐨勪繚鎶ゆ満鍒舵潵鎺у埗鍚屾銆傝岀涓縐嶆柟寮忎笉瀛樺湪榪欐牱鐨勯棶棰樸? 
   
  璇烽珮鎵嬫寚鐐癸紒鎴戜笉鏄庣櫧鐨勬槸錛屼負浠涔堜功涓婄殑渚嬪瓙榪樿緝澶氱殑閲囩敤絎簩縐嶆柟娉曪紵鑾潪瀹冩湁鑷繁鐨勪紭鍔匡紵錛? 
   


]]>
The "Double-Checked Locking is Broken" Declaration sigleleton 妯″紡http://www.shnenglu.com/michaelgao/archive/2008/10/23/64806.htmlmicheal's techmicheal's techThu, 23 Oct 2008 06:25:00 GMThttp://www.shnenglu.com/michaelgao/archive/2008/10/23/64806.htmlhttp://www.shnenglu.com/michaelgao/comments/64806.htmlhttp://www.shnenglu.com/michaelgao/archive/2008/10/23/64806.html#Feedback0http://www.shnenglu.com/michaelgao/comments/commentRss/64806.htmlhttp://www.shnenglu.com/michaelgao/services/trackbacks/64806.html The "Double-Checked Locking is Broken" Declaration

Signed by : David Bacon (IBM Research) Joshua Bloch (Javasoft), Jeff Bogda, Cliff Click (Hotspot JVM project), Paul Haahr, Doug Lea, Tom May, Jan-Willem Maessen, Jeremy Manson, John D. Mitchell (jGuru) Kelvin Nilsen, Bill Pugh, Emin Gun Sirer

Double-Checked Locking is widely cited and used as an efficient method for implementing lazy initialization in a multithreaded environment.

Unfortunately, it will not work reliably in a platform independent way when implemented in Java, without additional synchronization. When implemented in other languages, such as C++, it depends on the memory model of the processor, the reorderings performed by the compiler and the interaction between the compiler and the synchronization library. Since none of these are specified in a language such as C++, little can be said about the situations in which it will work. Explicit memory barriers can be used to make it work in C++, but these barriers are not available in Java.

To first explain the desired behavior, consider the following code:

// Single threaded version
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}
// other functions and members...
}

If this code was used in a multithreaded context, many things could go wrong. Most obviously, two or more Helper objects could be allocated. (We'll bring up other problems later). The fix to this is simply to synchronize the getHelper() method:

// Correct multithreaded version
class Foo {
private Helper helper = null;
public synchronized Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}
// other functions and members...
}

The code above performs synchronization every time getHelper() is called. The double-checked locking idiom tries to avoid synchronization after the helper is allocated:

// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}

Unfortunately, that code just does not work in the presence of either optimizing compilers or shared memory multiprocessors.

It doesn't work

There are lots of reasons it doesn't work. The first couple of reasons we'll describe are more obvious. After understanding those, you may be tempted to try to devise a way to "fix" the double-checked locking idiom. Your fixes will not work: there are more subtle reasons why your fix won't work. Understand those reasons, come up with a better fix, and it still won't work, because there are even more subtle reasons.

Lots of very smart people have spent lots of time looking at this. There is no way to make it work without requiring each thread that accesses the helper object to perform synchronization.

The first reason it doesn't work

The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.

If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.

Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor.

Doug Lea has written a more detailed description of compiler-based reorderings.

A test case showing that it doesn't work

Paul Jakubik found an example of a use of double-checked locking that did not work correctly. A slightly cleaned up version of that code is available here.

When run on a system using the Symantec JIT, it doesn't work. In particular, the Symantec JIT compiles

singletons[i].reference = new Singleton();

to the following (note that the Symantec JIT using a handle-based object allocation system).

0206106A   mov         eax,0F97E78h
0206106F call 01F6B210 ; allocate space for
; Singleton, return result in eax
02061074 mov dword ptr [ebp],eax ; EBP is &singletons[i].reference
; store the unconstructed object here.
02061077 mov ecx,dword ptr [eax] ; dereference the handle to
; get the raw pointer
02061079 mov dword ptr [ecx],100h ; Next 4 lines are
0206107F mov dword ptr [ecx+4],200h ; Singleton's inlined constructor
02061086 mov dword ptr [ecx+8],400h
0206108D mov dword ptr [ecx+0Ch],0F84030h

As you can see, the assignment to singletons[i].reference is performed before the constructor for Singleton is called. This is completely legal under the existing Java memory model, and also legal in C and C++ (since neither of them have a memory model).

A fix that doesn't work

Given the explanation above, a number of people have suggested the following code:

// (Still) Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
Helper h;
synchronized(this) {
h = helper;
if (h == null)
synchronized (this) {
h = new Helper();
} // release inner synchronization lock
helper = h;
}
}
return helper;
}
// other functions and members...
}

This code puts construction of the Helper object inside an inner synchronized block. The intuitive idea here is that there should be a memory barrier at the point where synchronization is released, and that should prevent the reordering of the initialization of the Helper object and the assignment to the field helper.

Unfortunately, that intuition is absolutely wrong. The rules for synchronization don't work that way. The rule for a monitorexit (i.e., releasing synchronization) is that actions before the monitorexit must be performed before the monitor is released. However, there is no rule which says that actions after the monitorexit may not be done before the monitor is released. It is perfectly reasonable and legal for the compiler to move the assignment helper = h; inside the synchronized block, in which case we are back where we were previously. Many processors offer instructions that perform this kind of one-way memory barrier. Changing the semantics to require releasing a lock to be a full memory barrier would have performance penalties.

More fixes that don't work

There is something you can do to force the writer to perform a full bidirectional memory barrier. This is gross, inefficient, and is almost guaranteed not to work once the Java Memory Model is revised. Do not use this. In the interests of science, Do not use it.

However , even with a full memory barrier being performed by the thread that initializes the helper object, it still doesn't work.

The problem is that on some systems, the thread which sees a non-null value for the helper field also needs to perform memory barriers.

Why? Because processors have their own locally cached copies of memory. On some processors, unless the processor performs a cache coherence instruction (e.g., a memory barrier), reads can be performed out of stale locally cached copies, even if other processors used memory barriers to force their writes into global memory.

I've created a separate web page with a discussion of how this can actually happen on an Alpha processor.

Is it worth the trouble?

For most applications, the cost of simply making the getHelper() method synchronized is not high. You should only consider this kind of detailed optimizations if you know that it is causing a substantial overhead for an application.

Very often, more high level cleverness, such as using the builtin mergesort rather than handling exchange sort (see the SPECJVM DB benchmark) will have much more impact.

Making it work for static singletons

If the singleton you are creating is static (i.e., there will only be one Helper created), as opposed to a property of another object (e.g., there will be one Helper for each Foo object, there is a simple and elegant solution.

Just define the singleton as a static field in a separate class. The semantics of Java guarantee that the field will not be initialized until the field is referenced, and that any thread which accesses the field will see all of the writes resulting from initializing that field.

class HelperSingleton {
static Helper singleton = new Helper();
}

It will work for 32-bit primitive values

Although the double-checked locking idiom cannot be used for references to objects, it can work for 32-bit primitive values (e.g., int's or float's). Note that it does not work for long's or double's, since unsynchronized reads/writes of 64-bit primitives are not guaranteed to be atomic.

// Correct Double-Checked Locking for 32-bit primitives
class Foo {
private int cachedHashCode = 0;
public int hashCode() {
int h = cachedHashCode;
if (h == 0)
synchronized(this) {
if (cachedHashCode != 0) return cachedHashCode;
h = computeHashCode();
cachedHashCode = h;
}
return h;
}
// other functions and members...
}

In fact, assuming that the computeHashCode function always returned the same result and had no side effects (i.e., idempotent), you could even get rid of all of the synchronization.

// Lazy initialization 32-bit primitives
// Thread-safe if computeHashCode is idempotent
class Foo {
private int cachedHashCode = 0;
public int hashCode() {
int h = cachedHashCode;
if (h == 0) {
h = computeHashCode();
cachedHashCode = h;
}
return h;
}
// other functions and members...
}

Making it work with explicit memory barriers

It is possible to make the double checked locking pattern work if you have explicit memory barrier instructions. For example, if you are programming in C++, you can use the code from Doug Schmidt et al.'s book:

// C++ implementation with explicit memory barriers
// Should work on any platform, including DEC Alphas
// From "Patterns for Concurrent and Distributed Objects",
// by Doug Schmidt
template <class TYPE, class LOCK> TYPE *
Singleton<TYPE, LOCK>::instance (void) {
// First check
TYPE* tmp = instance_;
// Insert the CPU-specific memory barrier instruction
// to synchronize the cache lines on multi-processor.
asm ("memoryBarrier");
if (tmp == 0) {
// Ensure serialization (guard
// constructor acquires lock_).
Guard<LOCK> guard (lock_);
// Double check.
tmp = instance_;
if (tmp == 0) {
tmp = new TYPE;
// Insert the CPU-specific memory barrier instruction
// to synchronize the cache lines on multi-processor.
asm ("memoryBarrier");
instance_ = tmp;
}
return tmp;
}

Fixing Double-Checked Locking using Thread Local Storage

Alexander Terekhov (TEREKHOV@de.ibm.com) came up clever suggestion for implementing double checked locking using thread local storage. Each thread keeps a thread local flag to determine whether that thread has done the required synchronization.
  class Foo {
/** If perThreadInstance.get() returns a non-null value, this thread
has done synchronization needed to see initialization
of helper */
private final ThreadLocal perThreadInstance = new ThreadLocal();
private Helper helper = null;
public Helper getHelper() {
if (perThreadInstance.get() == null) createHelper();
return helper;
}
private final void createHelper() {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
// Any non-null value would do as the argument here
perThreadInstance.set(perThreadInstance);
}
}

The performance of this technique depends quite a bit on which JDK implementation you have. In Sun's 1.2 implementation, ThreadLocal's were very slow. They are significantly faster in 1.3, and are expected to be faster still in 1.4. Doug Lea analyzed the performance of some techniques for implementing lazy initialization.

Under the new Java Memory Model

As of JDK5, there is a new Java Memory Model and Thread specification.

Fixing Double-Checked Locking using Volatile

JDK5 and later extends the semantics for volatile so that the system will not allow a write of a volatile to be reordered with respect to any previous read or write, and a read of a volatile cannot be reordered with respect to any following read or write. See this entry in Jeremy Manson's blog for more details.

With this change, the Double-Checked Locking idiom can be made to work by declaring the helper field to be volatile. This does not work under JDK4 and earlier.

// Works with acquire/release semantics for volatile
// Broken under current semantics for volatile
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}

Double-Checked Locking Immutable Objects

If Helper is an immutable object, such that all of the fields of Helper are final, then double-checked locking will work without having to use volatile fields. The idea is that a reference to an immutable object (such as a String or an Integer) should behave in much the same way as an int or float; reading and writing references to immutable objects are atomic.

Descriptions of double-check idiom




]]>
璁捐妯″紡瑙f瀽涔嬧斺擜bstractFactory妯″紡http://www.shnenglu.com/michaelgao/archive/2008/10/22/64685.htmlmicheal's techmicheal's techWed, 22 Oct 2008 02:44:00 GMThttp://www.shnenglu.com/michaelgao/archive/2008/10/22/64685.htmlhttp://www.shnenglu.com/michaelgao/comments/64685.htmlhttp://www.shnenglu.com/michaelgao/archive/2008/10/22/64685.html#Feedback0http://www.shnenglu.com/michaelgao/comments/commentRss/64685.htmlhttp://www.shnenglu.com/michaelgao/services/trackbacks/64685.html

0 寮曡█

0.1 鐩殑

       鏈枃妗g粰鍑鴻璁℃ā寮忎箣鈥斺擜bstractFactory妯″紡鐨勭畝鍖栬癄閲婏紝騫剁粰鍑哄叾C++瀹炵幇銆?/p>

0.2 璇存槑

Project

Design Pattern Explanation錛圔y K_Eckel錛?/p>

Authorization

Free Distributed but Ownership Reserved

Date

Test Bed

MS Visual C++ 6.0

0.3 鍙傝?/font>

       鍦ㄦ湰鏂囨。鐨勫啓浣滀腑錛屽弬鑰冧簡浠ヤ笅鐨勮祫婧愶紝鍦ㄦ鍒楀嚭琛ㄧず鎰熻阿錛?/p>

u       涔︾睄

[GoF 2000]錛欸oF,Design Patterns-Elements of Reusable Object-Oriented Software

Addison-Wesley 2000/9.

        [Martine 2003]錛歊obert C.Martine, Agile Software Development Principles, Patterns, and Practices, Pearson Education, 2003.

0.4 鑱旂郴浣滆?/font>

Author

K_Eckel

State

Candidate for Master’s Degree School of

E_mail

frwei@whu.edu.cn  

2 AbstractFactory妯″紡

2.1 闂

       鍋囪鎴戜滑瑕佸紑鍙戜竴嬈炬父鎴忥紝褰撶劧涓轟簡鍚稿紩鏇村鐨勪漢鐜╋紝娓告垙闅懼害涓嶈兘澶ぇ錛堣澶у閮芥病鏈変俊蹇冧簡錛屼及璁℃父鎴忎篃灝辨病鏈夊墠閫斾簡錛夛紝浣嗘槸涔熶笉鑳藉お綆鍗曪紙娌℃湁鎸戞垬鎬т篃涓嶇鍚堢帺瀹剁殑蹇冪悊錛夈備簬鏄垜浠氨鍙互閲囩敤榪欐牱涓縐嶅鐞嗙瓥鐣ワ細涓烘父鎴忚绔嬬瓑綰э紝鍒濈駭銆佷腑綰с侀珮綰х敋鑷蟲湁BT綰с傚亣璁句篃鏄繃鍏崇殑娓告垙錛屾瘡涓叧鍗¢兘鏈変竴浜涙墿錛坢onster錛夊畧鐫錛岀帺瀹惰鎶婅繖浜涙? 鐗╁共鎺夋墠鍙互榪囧叧銆備綔涓哄紑鍙戣咃紝鎴戜滑灝變笉寰椾笉鍒涘緩鎬墿鐨勭被錛岀劧鍚庡垵綰ф墿銆佷腑綰ф墿絳夐兘緇ф壙鑷墿綾伙紙褰撶劧涓嶅悓縐嶇被鐨勫垯闇瑕佸彟鍒涘緩綾伙紝浣嗘槸妯″紡鐩稿悓錛夈傚湪 姣忎釜鍏沖崱錛屾垜浠兘瑕佸垱寤烘墿鐨勫疄渚嬶紝渚嬪鍒濈駭灝卞垱寤哄垵綰ф墿錛堟湁寰堝縐嶇被錛夈佷腑綰у垱寤轟腑綰ф墿絳夈傚彲浠ユ兂璞″湪榪欎釜緋葷粺涓紝灝嗕細鏈夋垚鍗冧笂涓囩殑鎬墿瀹炰緥瑕佸垱 寤猴紝闂鏄繕瑕佷繚璇佸垱寤虹殑鏃跺欎笉浼氬嚭閿欙細鍒濈駭涓嶈兘鍒涘緩BT綰х殑鎬墿錛堢帺瀹跺氨閮侀椃浜嗭紝鐜╁涓閮侀椃錛屾父鎴忎篃灝辨寕鎸備簡錛夛紝鍙嶄箣涔熶笉鍙互銆?/p>

       AbstractFactory妯″紡灝辨槸鐢ㄦ潵瑙e喅榪欑被闂鐨勶細瑕佸垱寤轟竴緇勭浉鍏蟲垨鑰呯浉浜掍緷璧栫殑瀵硅薄銆?/p>

2.2 妯″紡閫夋嫨

       AbstractFactory妯″紡鍏稿瀷鐨勭粨鏋勫浘涓猴細


鍥?font face="Times New Roman">2-1
錛?font face="Times New Roman">AbstractFactoryPattern
緇撴瀯鍥?/p>

       AbstractFactory妯″紡鍏抽敭灝辨槸灝嗚繖涓緇勫璞$殑鍒涘緩灝佽鍒頒竴涓敤浜庡垱寤哄璞$殑綾伙紙ConcreteFactory錛変腑錛岀淮鎶よ繖鏍蜂竴涓垱寤虹被鎬繪瘮緇存姢n澶氱浉鍏沖璞$殑鍒涘緩榪囩▼瑕佺畝鍗曠殑澶氥?/p>

2.3 瀹炵幇

       AbstractFactory妯″紡鐨勫疄鐜版瘮杈冪畝鍗曪紝榪欓噷涓轟簡鏂逛究鍒濆鑰呯殑瀛︿範鍜屽弬鑰冿紝灝嗙粰鍑哄畬鏁寸殑瀹炵幇浠g爜錛堟墍鏈変唬鐮侀噰鐢?font face="Times New Roman">C++瀹炵幇錛屽茍鍦?font face="Times New Roman">VC 6.0涓嬫祴璇曡繍琛岋級銆?br>

浠g爜鐗囨柇1錛?/font>Product.h
//Product.h

#ifndef _PRODUCT_H_
#define _PRODUCT_H_

class AbstractProductA
{
public:
 virtual ~AbstractProductA();

protected:
 AbstractProductA();

private:

};

class AbstractProductB
{
public:
 virtual ~AbstractProductB();

protected:
 AbstractProductB();

private:

};

class ProductA1:public AbstractProductA
{
public:
 ProductA1();

 ~ProductA1();

protected:

private:

};

class ProductA2:public AbstractProductA
{
public:
 ProductA2();

 ~ProductA2();

protected:

private:

};

class ProductB1:public AbstractProductB
{
public:
 ProductB1();

 ~ProductB1();

protected:

private:

};

class ProductB2:public AbstractProductB
{
public:
 ProductB2();

 ~ProductB2();

protected:

private:

};

#endif //~_PRODUCT_H_

浠g爜鐗囨柇2錛?/font>Product.cpp
//Product.cpp

#include "Product.h"

#include <iostream>
using namespace std;

AbstractProductA::AbstractProductA()
{

}

AbstractProductA::~AbstractProductA()
{

}

AbstractProductB::AbstractProductB()
{

}

AbstractProductB::~AbstractProductB()
{

}

ProductA1::ProductA1()
{
 cout<<"ProductA1..."<<endl;
}

ProductA1::~ProductA1()
{

}

ProductA2::ProductA2()
{
 cout<<"ProductA2..."<<endl;
}

ProductA2::~ProductA2()
{

}

ProductB1::ProductB1()
{
 cout<<"ProductB1..."<<endl;
}

ProductB1::~ProductB1()
{

}

ProductB2::ProductB2()
{
 cout<<"ProductB2..."<<endl;
}

ProductB2::~ProductB2()
{

}

浠g爜鐗囨柇3錛?/font>AbstractFactory.h
//AbstractFactory.h

#ifndef _ABSTRACTFACTORY_H_
#define _ABSTRACTFACTORY_H_

class AbstractProductA;
class AbstractProductB;

class AbstractFactory
{
public:
 virtual ~AbstractFactory();

 virtual AbstractProductA* CreateProductA() = 0;

 virtual AbstractProductB* CreateProductB() = 0;

protected:
 AbstractFactory();

private:

};

class ConcreteFactory1:public AbstractFactory
{
public:
 ConcreteFactory1();

 ~ConcreteFactory1();

 AbstractProductA* CreateProductA();

 AbstractProductB* CreateProductB();

protected:

private:

};

class ConcreteFactory2:public AbstractFactory
{
public:
 ConcreteFactory2();

 ~ConcreteFactory2();

 AbstractProductA* CreateProductA();

 AbstractProductB* CreateProductB();

protected:

private:

};
#endif //~_ABSTRACTFACTORY_H_

浠g爜鐗囨柇4錛?/font>AbstractFactory.cpp
//AbstractFactory.cpp

#include "AbstractFactory.h"
#include "Product.h"

#include <iostream>
using namespace std;

AbstractFactory::AbstractFactory()
{

}

AbstractFactory::~AbstractFactory()
{

}

ConcreteFactory1::ConcreteFactory1()
{

}

ConcreteFactory1::~ConcreteFactory1()
{

}

AbstractProductA* ConcreteFactory1::CreateProductA()
{
 return new ProductA1();
}

AbstractProductB* ConcreteFactory1::CreateProductB()
{
 return new ProductB1();
}

ConcreteFactory2::ConcreteFactory2()
{

}

ConcreteFactory2::~ConcreteFactory2()
{

}

AbstractProductA* ConcreteFactory2::CreateProductA()
{
 return new ProductA2();
}

AbstractProductB* ConcreteFactory2::CreateProductB()
{
 return new ProductB2();
}

浠g爜鐗囨柇5錛?/font>main.cpp
//main.cpp

#include "AbstractFactory.h"

#include <iostream>
using namespace std;

int main(int argc,char* argv[])
{
 AbstractFactory* cf1 = new ConcreteFactory1();

 cf1->CreateProductA();
 cf1->CreateProductB();

 AbstractFactory* cf2 = new ConcreteFactory2();
 cf2->CreateProductA();
 cf2->CreateProductB();

 return 0;
}

       AbstractFactory妯″紡鐨勫疄鐜頒唬鐮佸緢綆鍗曪紝鍦ㄦ祴璇曠▼搴忎腑鍙互鐪嬪埌錛屽綋鎴戜滑瑕佸垱寤轟竴緇勫璞★紙ProductA1錛孭roductA2錛夌殑鏃跺欐垜浠彧鐢ㄧ淮鎶や竴涓垱寤哄璞★紙ConcreteFactory1錛夛紝澶уぇ綆鍖栦簡緇存姢鐨勬垚鏈拰宸ヤ綔銆?/font>

2.4 璁ㄨ

       AbstractFactory妯″紡鍜孎actory妯″紡鐨勫尯鍒槸鍒濆錛堜嬌鐢級璁捐妯″紡鏃跺欑殑涓涓鏄撳紩璧峰洶鎯戠殑鍦版柟銆傚疄闄呬笂錛孉bstractFactory妯″紡鏄負鍒涘緩涓緇勶紙鏈夊綾伙級鐩稿叧鎴栦緷璧栫殑瀵硅薄鎻愪緵鍒涘緩鎺ュ彛錛岃孎actory妯″紡姝e鎴戝湪鐩稿簲鐨勬枃妗d腑鍒嗘瀽鐨勬槸涓?strong>涓綾?/strong>瀵硅薄鎻愪緵鍒涘緩鎺ュ彛鎴栧歡榪熷璞$殑鍒涘緩鍒板瓙綾諱腑瀹炵幇銆傚茍涓斿彲浠ョ湅鍒幫紝AbstractFactory妯″紡閫氬父閮芥槸浣跨敤Factory妯″紡瀹炵幇錛圕oncreteFactory1錛夈?/font>




]]>
緙栬緫decorate紼嬪簭鏃墮亣鍒頒竴涓棶棰?/title><link>http://www.shnenglu.com/michaelgao/archive/2008/10/16/64170.html</link><dc:creator>micheal's tech</dc:creator><author>micheal's tech</author><pubDate>Thu, 16 Oct 2008 09:04:00 GMT</pubDate><guid>http://www.shnenglu.com/michaelgao/archive/2008/10/16/64170.html</guid><wfw:comment>http://www.shnenglu.com/michaelgao/comments/64170.html</wfw:comment><comments>http://www.shnenglu.com/michaelgao/archive/2008/10/16/64170.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/michaelgao/comments/commentRss/64170.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/michaelgao/services/trackbacks/64170.html</trackback:ping><description><![CDATA[class Decorator:public Beverage<br>{<br>    public:<br>        Decorator(Beverage * com);<br>        virtual ~Decorator();<br>        virtual string get_descrption();<br>   <span style="background-color: yellow;"> protected:</span><br>      <span style="background-color: yellow;">  Beverage * component;</span><br><br><br>};<br><br> 鑰孧ilkDecorator緇ф壙浜咲ecorator,濡傛灉component 涓虹鏈夌殑鍒橫ilkDecorator渚夸笉鑳借闂?br><br>濡傛灉milkDecorator 璁捐鎴愯繖鏍峰氨涓嶄細榪濆弽浜嗗皝瑁呯殑鍘熷垯銆?br>鍩烘湰涓婂彧鏈変竴涓尯鍒紝灝辨槸protect鎴愬憳鑳借媧劇敓綾昏闂紒鑰屾淳鐢熺被瀵筽rivate娌℃湁鐗規畩璁塊棶鏉冿紒 <br><br><img src ="http://www.shnenglu.com/michaelgao/aggbug/64170.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/michaelgao/" target="_blank">micheal's tech</a> 2008-10-16 17:04 <a href="http://www.shnenglu.com/michaelgao/archive/2008/10/16/64170.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>UML涓竴浜涚鍙風殑鎰忎箟http://www.shnenglu.com/michaelgao/archive/2008/10/13/63889.htmlmicheal's techmicheal's techMon, 13 Oct 2008 06:53:00 GMThttp://www.shnenglu.com/michaelgao/archive/2008/10/13/63889.htmlhttp://www.shnenglu.com/michaelgao/comments/63889.htmlhttp://www.shnenglu.com/michaelgao/archive/2008/10/13/63889.html#Feedback0http://www.shnenglu.com/michaelgao/comments/commentRss/63889.htmlhttp://www.shnenglu.com/michaelgao/services/trackbacks/63889.htmlhttp://book.csdn.net/bookfiles/575/10057518902.shtml

铏氱嚎綆ご琛ㄧず“渚濊禆鍏崇郴”錛屼緷璧栨湁“浣跨敤”鐨勮涔夛紝姣斿鎮h呬笌鍖葷敓鐨勫叧緋匯?br>瀹炵嚎綆ご琛ㄧず“甯︿簡瀵艱埅琛岀殑鍏寵仈鍏崇郴”錛屼粠涓涓被鍒板彟涓綾匯?br>浣跨敤瀹炵嚎綆ご鏃墮氬父浼氬甫涓?#8220;澶氶噸鎬?#8221;鐨勮〃杈炬柟寮忋傚錛氫竴瀵瑰錛屼竴瀵逛竴錛屽瀵瑰絳夌瓑

甯歌鐨勫叧緋繪湁錛氫竴鑸寲鍏崇郴錛圙eneralization錛夛紝鍏寵仈鍏崇郴錛圓ssociation錛夛紝鑱氬悎鍏崇郴錛圓ggregation錛夛紝鍚堟垚鍏崇郴錛圕omposition錛夛紝渚濊禆鍏崇郴錛圖ependency錛夈?/font>

      鍏朵腑錛岃仛鍚堝叧緋伙紙Aggregation錛夛紝鍚堟垚鍏崇郴錛圕omposition錛夊睘浜庡叧鑱斿叧緋伙紙Association錛夈?/font>

      涓鑸叧緋昏〃鐜頒負緇ф壙鎴栧疄鐜板叧緋?is a)錛屽叧鑱斿叧緋昏〃鐜頒負鍙橀噺(has a )錛屼緷璧栧叧緋昏〃鐜頒負鍑芥暟涓殑鍙傛暟(use a)銆?/font>

      涓鑸寲鍏崇郴錛氳〃紺轟負綾諱笌綾諱箣闂寸殑緇ф壙鍏崇郴錛屾帴鍙d笌鎺ュ彛涔嬮棿鐨勭戶鎵匡紝綾誨鎺ュ彛鐨勫疄鐜板叧緋匯?br>      琛ㄧず鏂規硶錛?鐢ㄤ竴涓┖蹇冪澶達紜瀹炵嚎錛岀澶存寚鍚戠埗綾匯傛垨絀哄績綆ご錛嬭櫄綰匡紝濡傛灉鐖剁被鏄帴鍙c?/font>

      鍏寵仈鍏崇郴錛氱被涓庣被涔嬮棿鐨勮仈鎺ワ紝瀹冧嬌涓涓被鐭ラ亾鍙︿竴涓被鐨勫睘鎬у拰鏂規硶銆?br>      琛ㄧず鏂規硶錛氱敤 瀹炵嚎錛嬬澶達紝 綆ご鎸囧悜琚嬌鐢ㄧ殑綾匯?/font>

      鑱氬悎鍏崇郴錛氭槸鍏寵仈鍏崇郴鐨勪竴縐嶏紝鏄己鐨勫叧鑱斿叧緋匯傝仛鍚堝叧緋繪槸鏁翠綋鍜屼釜浣撶殑鍏崇郴銆傚叧鑱斿叧緋葷殑涓や釜綾誨浜庡悓涓灞傛涓婏紝鍟婅仛鍚堝叧緋諱袱涓被澶勪簬涓嶅悓鐨勫眰嬈★紝涓涓槸鏁翠綋錛屼竴涓槸閮ㄥ垎銆?br>      琛ㄧず鏂規硶錛氱┖蹇冭彵褰紜瀹炵嚎錛嬬澶達紝綆ご鎸囧悜閮ㄥ垎銆?/font>

      鍚堟垚鍏崇郴錛氭槸鍏寵仈鍏崇郴鐨勪竴縐嶏紝鏄瘮鑱氬悎鍏崇郴寮虹殑鍏崇郴銆傚畠瑕佹眰鏅氱殑鑱氬悎鍏崇郴涓唬琛ㄦ暣浣撶殑瀵硅薄璐熻矗浠h〃閮ㄥ垎鐨勫璞$殑鐢熷懡鍛ㄦ湡錛屽悎鎴愬叧緋諱笉鑳藉叡浜?br>      琛ㄧず鏂規硶錛氬疄蹇冭彵褰紜瀹炵嚎錛嬬澶達紝

      渚濊禆鍏崇郴錛氭槸綾諱笌綾諱箣闂寸殑榪炴帴錛岃〃紺轟竴涓被渚濊禆浜庡彟涓涓被鐨勫畾涔夈備緥濡傚鏋淎渚濊禆浜嶣錛屽垯B浣撶幇涓哄眬閮ㄥ彉閲忥紝鏂規硶鐨勫弬鏁般佹垨闈欐佹柟娉曠殑璋冪敤銆?br>      琛ㄧず鏂規硶錛氳櫄綰匡紜綆ご


鍥句竴:

uploads/200706/04_211918_1121523.jpg


姝ゅ疄綰跨澶磋〃紺? 緇ф壙, 浠庝竴涓潪鎺ュ彛綾葷殑緇ф壙.

鍥句簩:
uploads/200706/04_212112_1121525gl.jpg


閭f潯榪炵嚎琛ㄧず鍙屽悜鍏寵仈:
鐪嬪乏杈? Flight鎵紨assignedFights瑙掕壊, 鏈?鍒?涓狿lane璺熶粬鍏寵仈(涓涓埅鐝涔堝彇娑堜簡娌℃湁椋炴満,瑕佷箞鍙兘瀵瑰簲涓鏋墮鏈?
鐪嬪彸杈? Plane鎵紨鐫assignedPlane瑙掕壊, 鏈?鍒板涓狥light璺熶粬鍏寵仈(涓涓鏈哄彲浠ュ弬涓庡涓埅鐝? 涔熷彲浠ュ仠鍦ㄤ粨搴撻噷闈㈢儌鎺?

鍥句笁:
uploads/200706/04_213002_1121526dxgl.jpg


閭f潯榪炵嚎琛ㄧず鍗曞悜鍏寵仈:
鍩烘湰鐨勬剰涔夎窡涓婇潰鐨勬槸涓鏍風殑, 鍞竴涓嶅悓鐨勬槸, 鍙寵竟鐨勭被瀵瑰乏杈圭殑綾繪槸涓鏃犳墍鐭ョ殑.

鍥懼洓:
uploads/200706/04_213232_1121527rjb.jpg


閭d釜澶х殑鍖呭洿鐨勬鍙蔣浠跺寘, 鍚嶅瓧涓篈ccount, 灝變竴浜涘彲浠ュ綊綾葷殑綾誨寘瑁呰搗鏉?

鍥句簲:
uploads/200706/04_213441_1121529xjc.gif


濡傛铏氱嚎鐨勭澶磋〃紺哄疄鐜頒竴涓帴鍙?

鍥懼叚:
uploads/200706/04_213626_11215210gll.jpg


姘村鉤鐨勮繛綰胯繕鏄〃紺轟笂闈㈡墍璇寸殑鍏寵仈, 浣嗕粠鍏寵仈榪炵嚎涓紩浼稿嚭鏉ョ殑铏氱嚎, 榪欐剰鍛沖綋Flight綾葷殑涓涓疄渚嬪叧鑱斿埌 FrequentFlyer 綾葷殑涓涓疄渚嬫椂錛屽皢浼氫駭鐢?MileageCredit 綾葷殑涓涓疄渚?

鍥句竷:
uploads/200706/04_213911_11215211jbjh.jpg


甯﹁彵褰㈢殑綆ご琛ㄧず鍩烘湰鑱氬悎, 鐢變笂鍥劇煡閬? Wheel綾繪壆婕攚heels瑙掕壊, 鑱氬悎4涓埌Car瀵硅薄閲岄潰鍘?
絀哄績鐨勮彵褰㈣〃紺篧heel瀵硅薄騫朵笉闅廋ar鐨勫垱寤鴻屽垱寤?閿姣佽岄攢姣?

鍥懼叓:
uploads/200706/04_214248_11215212zhjh.jpg


鎰忎箟鍜屼笂闈㈢被浼? 鍞竴涓嶅悓鐨勬槸, 瀹炲績鑿卞艦琛ㄧずDepartment瀵硅薄闅廋ompany瀵硅薄鐨勫垱寤鴻屽垱寤?閿姣佽岄攢姣?

鍥句節:
uploads/200706/04_214435_11215213fs.gif


琛ㄧず鍙嶅皠鍏寵仈, 鏄劇ず涓涓狤mployee綾誨浣曢氳繃manager / manages瑙掕壊涓庡畠鏈韓鐩稿叧銆傚綋涓涓被鍏寵仈鍒板畠鏈韓鏃訛紝榪欏茍涓嶆剰鍛崇潃綾葷殑瀹炰緥涓庡畠鏈韓鐩稿叧錛岃屾槸綾葷殑涓涓疄渚嬩笌綾葷殑鍙︿竴涓疄渚嬬浉鍏熾?br>


]]>
璁捐妯″紡瑙f瀽涔嬧斺擮bserver妯″紡錛坘_eckel杞嚜寰蔣楂樻牎鍗氬K_eckel's mindview錛?http://www.shnenglu.com/michaelgao/archive/2008/10/10/63633.htmlmicheal's techmicheal's techFri, 10 Oct 2008 03:04:00 GMThttp://www.shnenglu.com/michaelgao/archive/2008/10/10/63633.htmlhttp://www.shnenglu.com/michaelgao/comments/63633.htmlhttp://www.shnenglu.com/michaelgao/archive/2008/10/10/63633.html#Feedback0http://www.shnenglu.com/michaelgao/comments/commentRss/63633.htmlhttp://www.shnenglu.com/michaelgao/services/trackbacks/63633.html

0 寮曡█

0.1 鐩殑

       鏈枃妗g粰鍑鴻璁℃ā寮忎箣鈥斺擮bserver妯″紡鐨勭畝鍖栬癄閲婏紝騫剁粰鍑哄叾C++瀹炵幇銆?/p>

0.2 璇存槑

Project

Design Pattern Explanation錛圔y K_Eckel錛?/p>

Authorization

Free Distributed but Ownership Reserved

Date

Test Bed

MS Visual C++ 6.0

0.3 鍙傝?/font>

       鍦ㄦ湰鏂囨。鐨勫啓浣滀腑錛屽弬鑰冧簡浠ヤ笅鐨勮祫婧愶紝鍦ㄦ鍒楀嚭琛ㄧず鎰熻阿錛?/p>

u       涔︾睄

[GoF 2000]錛欸oF,Design Patterns-Elements of Reusable Object-Oriented Software

Addison-Wesley 2000/9.

        [Martine 2003]錛歊obert C.Martine, Agile Software Development Principles, Patterns, and Practices, Pearson Education, 2003.

0.4 鑱旂郴浣滆?/font>

Author

K_Eckel

State

Candidate for Master’s Degree School of

E_mail

frwei@whu.edu.cn  

2 Observer妯″紡

2.1 闂

       Observer妯″紡搴旇鍙互璇存槸搴旂敤鏈澶氥佸獎鍝嶆渶騫跨殑妯″紡涔嬩竴錛屽洜涓篛bserver鐨勪竴涓疄渚婱odel/View/Control錛圡VC錛夌粨鏋勫湪緋葷粺寮鍙戞灦鏋勮璁′腑鏈夌潃寰堥噸瑕佺殑鍦頒綅鍜屾剰涔夛紝MVC瀹炵幇浜嗕笟鍔¢昏緫鍜岃〃紺哄眰鐨勮В鑰︺?strong>涓漢涔熻涓?/strong>Observer妯″紡鏄蔣浠跺紑鍙戣繃紼嬩腑蹇呴』瑕佹帉鎻″拰浣跨敤鐨勬ā寮忎箣涓銆傚湪MFC涓紝Doc/View錛堟枃妗h鍥劇粨鏋勶級鎻愪緵浜嗗疄鐜癕VC鐨勬鏋剁粨鏋勶紙鏈変竴涓粠璁捐妯″紡錛圤bserver妯″紡錛夌殑瑙掑害鍒嗘瀽鍒嗘瀽Doc/View鐨勬枃绔犳鍦ㄨ繘涓姝ョ殑鎾板啓褰撲腑錛岄仐鎲劇殑鏄椂闂達細錛夛級銆傚湪Java闃靛涓紝Struts鍒欐彁渚涘拰MFC涓璂oc/View緇撴瀯綾諱技鐨勫疄鐜癕VC鐨勬鏋躲傚彟澶朖ava璇█鏈韓灝辨彁渚涗簡Observer妯″紡鐨勫疄鐜版帴鍙o紝榪欏皢鍦ㄨ璁轟腑緇欏嚭銆?/p>

       褰撶劧錛孧VC鍙槸Observer妯″紡鐨勪竴涓疄渚嬨侽bserver妯″紡瑕佽В鍐崇殑闂涓猴細寤虹珛涓涓竴錛圫ubject錛夊澶氾紙Observer錛? 鐨勪緷璧栧叧緋伙紝騫朵笖鍋氬埌褰?#8220;涓”鍙樺寲鐨勬椂鍊欙紝渚濊禆榪欎釜“涓”鐨勫涔熻兘澶熷悓姝ユ敼鍙樸傛渶甯歌鐨勪竴涓緥瀛愬氨鏄細瀵瑰悓涓緇勬暟鎹繘琛岀粺璁″垎鏋愭椂鍊欙紝鎴戜滑甯屾湜鑳藉鎻愪緵澶? 縐嶅艦寮忕殑琛ㄧず錛堜緥濡備互琛ㄦ牸榪涜緇熻鏄劇ず銆佹煴鐘跺浘緇熻鏄劇ず銆佺櫨鍒嗘瘮緇熻鏄劇ず絳夛級銆傝繖浜涜〃紺洪兘渚濊禆浜庡悓涓緇勬暟鎹紝鎴戜滑褰撶劧闇瑕佸綋鏁版嵁鏀瑰彉鐨勬椂鍊欙紝鎵鏈夌殑緇熻鐨? 鏄劇ず閮借兘澶熷悓鏃舵敼鍙樸侽bserver妯″紡灝辨槸瑙e喅浜嗚繖涓涓棶棰樸?/p>

2.2 妯″紡閫夋嫨

       Observer妯″紡鍏稿瀷鐨勭粨鏋勫浘涓猴細


鍥?font face="Times New Roman">2-1
錛?font face="Times New Roman">Observer Pattern
緇撴瀯鍥?/p>

       榪欓噷鐨勭洰鏍?font face="Times New Roman">Subject鎻愪緵渚濊禆浜庡畠鐨勮瀵熻?font face="Times New Roman">Observer鐨勬敞鍐岋紙Attach錛夊拰娉ㄩ攢錛?font face="Times New Roman">Detach錛夋搷浣滐紝騫朵笖鎻愪緵浜嗕嬌寰椾緷璧栦簬瀹冪殑鎵鏈夎瀵熻呭悓姝ョ殑鎿嶄綔錛?font face="Times New Roman">Notify錛夈傝瀵熻?font face="Times New Roman">Observer鍒欐彁渚涗竴涓?font face="Times New Roman">Update鎿嶄綔錛屾敞鎰忚繖閲岀殑Observer鐨?font face="Times New Roman">Update鎿嶄綔騫朵笉鍦?font face="Times New Roman">Observer鏀瑰彉浜?font face="Times New Roman">Subject鐩爣鐘舵佺殑鏃跺欏氨瀵硅嚜宸辮繘琛屾洿鏂幫紝榪欎釜鏇存柊鎿嶄綔瑕佸歡榪熷埌Subject瀵硅薄鍙戝嚭Notify閫氱煡鎵鏈?font face="Times New Roman">Observer榪涜淇敼錛堣皟鐢?font face="Times New Roman">Update錛夈?/p>

2.3 瀹炵幇

       Observer妯″紡鐨勫疄鐜版湁浜涚壒鐐癸紝榪欓噷涓轟簡鏂逛究鍒濆鑰呯殑瀛︿範鍜屽弬鑰冿紝灝嗙粰鍑哄畬鏁寸殑瀹炵幇浠g爜錛堟墍鏈変唬鐮侀噰鐢?font face="Times New Roman">C++瀹炵幇錛屽茍鍦?font face="Times New Roman">VC 6.0涓嬫祴璇曡繍琛岋級銆?br>

浠g爜鐗囨柇1錛?/font>Subject.h
//Subject.h

#ifndef _SUBJECT_H_
#define _SUBJECT_H_

#include <list>
#include <string>
using namespace std;

typedef string State;

class Observer;

class Subject
{
public:
 virtual ~Subject();

 virtual void Attach(Observer* obv);

 virtual void Detach(Observer* obv);

 virtual void Notify();

 virtual void SetState(const State& st) = 0;

 virtual State GetState() = 0;

protected:
 Subject();

private:
 list<Observer* >* _obvs;

};

class ConcreteSubject:public Subject
{
public:
 ConcreteSubject();

 ~ConcreteSubject();

 State GetState();

 void SetState(const State& st);

protected:

private:
 State _st;

};

#endif //~_SUBJECT_H_

浠g爜鐗囨柇2錛?/font>Subject.cpp
//Subject.cpp

#include "Subject.h"
#include "Observer.h"

#include <iostream>
#include <list>
using namespace std;

typedef string state;

Subject::Subject()
{
 //****鍦ㄦā鏉跨殑浣跨敤涔嬪墠涓瀹氳new錛屽垱寤?/font>
 _obvs = new list<Observer*>;

}

Subject::~Subject()
{
 
}

void Subject::Attach(Observer* obv)
{
 
 _obvs->push_front(obv);
}

void Subject::Detach(Observer* obv)
{
 if (obv != NULL)
  _obvs->remove(obv);
}

void Subject::Notify()
{
 
 list<Observer*>::iterator it;

 it = _obvs->begin();

 for (;it != _obvs->end();it++)
 {
  //鍏充簬妯℃澘鍜?/font>iterator鐨勭敤娉?/font>

  (*it)->Update(this);
 }
}

ConcreteSubject::ConcreteSubject()
{
 _st = '\0';
}

ConcreteSubject::~ConcreteSubject()
{
 
}


State ConcreteSubject::GetState()
{
 return _st;
}

void ConcreteSubject::SetState(const State& st)
{
 _st = st;
}

浠g爜鐗囨柇3錛?/font>Observer.h
//Observer.h

#ifndef _OBSERVER_H_
#define _OBSERVER_H_

#include "Subject.h"

#include <string>
using namespace std;

typedef string State;

class Observer
{
public:
 virtual ~Observer();

 virtual void Update(Subject* sub) = 0;

 virtual void PrintInfo() = 0;

protected:
 Observer();

 State _st;

private:

};

class ConcreteObserverA:public Observer
{
public:
 virtual Subject* GetSubject();
 
 ConcreteObserverA(Subject* sub);

 virtual ~ConcreteObserverA();

 //浼犲叆Subject浣滀負鍙傛暟錛岃繖鏍峰彲浠ヨ涓涓?/font>View灞炰簬澶氫釜鐨?/font>Subject銆?/font>
 void  Update(Subject* sub);

 void PrintInfo();

protected:

private:
 Subject* _sub;

};

class ConcreteObserverB:public Observer
{
public:
 virtual Subject* GetSubject();
 
 ConcreteObserverB(Subject* sub);

 virtual ~ConcreteObserverB();

 //浼犲叆Subject浣滀負鍙傛暟錛岃繖鏍峰彲浠ヨ涓涓?/font>View灞炰簬澶氫釜鐨?/font>Subject銆?/font>
 void  Update(Subject* sub);

 void PrintInfo();

protected:

private:
 Subject* _sub;

};

#endif //~_OBSERVER_H_

浠g爜鐗囨柇4錛?/font>Observer.cpp
//Observer.cpp

#include "Observer.h"
#include "Subject.h"

#include <iostream>
#include <string>
using namespace std;

Observer::Observer()
{
 _st = '\0';

}

Observer::~Observer()
{

}


ConcreteObserverA::ConcreteObserverA(Subject* sub)
{
 _sub = sub;

 _sub->Attach(this);
}

ConcreteObserverA::~ConcreteObserverA()
{
 _sub->Detach(this);

 if (_sub != 0)
 {
  delete _sub;
 }
}

Subject* ConcreteObserverA::GetSubject()

 return _sub;
}

void ConcreteObserverA::PrintInfo()
{
 cout<<"ConcreteObserverA observer.... "<<_sub->GetState()<<endl;
}

void ConcreteObserverA::Update(Subject* sub)
{
 _st = sub->GetState();

 PrintInfo();
}

ConcreteObserverB::ConcreteObserverB(Subject* sub)
{
 _sub = sub;

 _sub->Attach(this);
}

ConcreteObserverB::~ConcreteObserverB()
{
 _sub->Detach(this);

 if (_sub != 0)
 {
  delete _sub;
 }
}

Subject* ConcreteObserverB::GetSubject()

 return _sub;
}

void ConcreteObserverB::PrintInfo()
{
 cout<<"ConcreteObserverB observer.... "<<_sub->GetState()<<endl;
}

void ConcreteObserverB::Update(Subject* sub)
{
 _st = sub->GetState();

 PrintInfo();
}

浠g爜鐗囨柇5錛?/font>main.cpp
//main.cpp

#include "Subject.h"
#include "Observer.h"

#include <iostream>
using namespace std;

int main(int argc,char* argv[])
{
 ConcreteSubject* sub = new ConcreteSubject();

 Observer* o1 = new ConcreteObserverA(sub);

 Observer* o2 = new ConcreteObserverB(sub);

 sub->SetState("old");

 sub->Notify();

 sub->SetState("new"); //涔熷彲浠ョ敱Observer璋冪敤

 sub->Notify();

 return 0;
}

鍦∣bserver妯″紡鐨勫疄鐜頒腑錛孲ubject緇存姢涓涓猯ist浣滀負瀛樺偍鍏舵墍鏈夎瀵熻呯殑瀹瑰櫒銆傛瘡褰撹皟鐢∟otify鎿嶄綔灝遍亶鍘唋ist涓殑Observer瀵硅薄錛屽茍騫挎挱閫氱煡鏀瑰彉鐘舵侊紙璋冪敤Observer鐨刄pdate鎿嶄綔錛夈傜洰鏍囩殑鐘舵乻tate鍙互鐢盨ubject鑷繁鏀瑰彉錛堢ず渚嬶級錛屼篃鍙互鐢監bserver鐨勬煇涓搷浣滃紩璧穝tate鐨勬敼鍙橈紙鍙皟鐢⊿ubject鐨凷etState鎿嶄綔錛夈侼otify鎿嶄綔鍙互鐢盨ubject鐩爣涓誨姩騫挎挱錛堢ず渚嬶級錛屼篃鍙互鐢監bserver瑙傚療鑰呮潵璋冪敤錛堝洜涓篛bserver緇存姢涓涓寚鍚慡ubject鐨勬寚閽堬級銆?/font>

       榪愯紺轟緥紼嬪簭錛屽彲浠ョ湅鍒板綋Subject澶勪簬鐘舵?#8220;old”鏃跺欙紝渚濊禆浜庡畠鐨勪袱涓瀵熻呴兘鏄劇ず“old”錛屽綋鐩爣鐘舵佹敼鍙樹負“new”鐨勬椂鍊欙紝渚濊禆浜庡畠鐨勪袱涓瀵熻呬篃閮芥敼鍙樹負“new”銆?/font>

2.4 璁ㄨ

       Observer鏄獎鍝嶆瀬涓烘繁榪滅殑妯″紡涔嬩竴錛屼篃鏄湪澶у瀷緋葷粺寮鍙戣繃紼嬩腑瑕佺敤鍒扮殑妯″紡涔嬩竴銆傞櫎浜哅FC銆丼truts鎻愪緵浜哅VC鐨勫疄鐜版鏋訛紝鍦↗ava璇█涓繕鎻愪緵浜嗕笓闂ㄧ殑鎺ュ彛瀹炵幇Observer妯″紡錛氶氳繃涓撻棬鐨勭被Observable鍙奜bserver鎺ュ彛鏉ュ疄鐜癕VC緙栫▼妯″紡錛屽叾UML鍥懼彲浠ヨ〃紺轟負錛?/font>

 


Java涓疄鐜癕VC鐨刄ML鍥俱?/font>

榪欓噷鐨凮bserver灝辨槸瑙傚療鑰咃紝Observable鍒欏厖褰撶洰鏍嘢ubject鐨勮鑹層?/font>

       Observer妯″紡涔熺О涓哄彂甯冿紞璁㈤槄錛坧ublish-subscribe錛夛紝鐩爣灝辨槸閫氱煡鐨勫彂甯冭咃紝瑙傚療鑰呭垯鏄氱煡鐨勮闃呰咃紙鎺ュ彈閫氱煡錛夈?/font>




]]>
C++涓帴鍙d笌瀹炵幇鐨勫垎紱誨彞鏌勭被http://www.shnenglu.com/michaelgao/archive/2008/10/07/63401.htmlmicheal's techmicheal's techTue, 07 Oct 2008 08:13:00 GMThttp://www.shnenglu.com/michaelgao/archive/2008/10/07/63401.htmlhttp://www.shnenglu.com/michaelgao/comments/63401.htmlhttp://www.shnenglu.com/michaelgao/archive/2008/10/07/63401.html#Feedback0http://www.shnenglu.com/michaelgao/comments/commentRss/63401.htmlhttp://www.shnenglu.com/michaelgao/services/trackbacks/63401.html
鍙ユ焺綾繪槸瀛樺偍鍜岀鐞嗗熀綾繪寚閽堢殑涓涓被
闇瑕佸彞鏌勭被鐨勮儗鏅細
1錛夊湪瀵瑰畨鍏ㄨ姹傚緢楂樼殑棰嗗煙錛屽嵆浣挎牳蹇冨疄鐜板凡緇忓皝闂湪搴撲腑涓嶅彲瑙侊紝浣嗗ご鏂囦歡涓彉閲忓畾涔変粛鍙兘鏇濋湶涓浜涘唴閮ㄤ俊鎭?
2錛夊湪璁捐鍒濇湡銆佸疄鐜伴儴鍒嗕細緇忓父鍙樺姩錛岀敋鑷沖ご鏂囦歡涓彉閲忓畾涔変篃闇瑕佺粡甯稿彉鍔紝鍥犳鍦ㄩ噸緙栬瘧鐨勬椂鍊欏ご鏂囦歡涔熼渶瑕佺紪璇戯紝
鏈夋椂鍊欏鑷寸紪璇戞椂闂磋繃闀褲?br> 鍙ユ焺綾誨氨鏄負浜嗚В鍐寵繖綾婚棶棰?
// Handle.h
class Implement; //榪欓噷鏄鐪熸瀹炵幇鍔熻兘鐨勭被鐨勫0鏄?br>
class ImplementHandle //榪欐槸Implement綾葷殑鍙ユ焺綾?br>{
public:
ImplementHandle():lpImplementInstance(NULL){lpImplementInstance = new Implement;}
~ImplementHandle(){ delete lpImplementInstance ;}
public:
// Interface_FOO() 鏄彞鏌勭被鎻愪緵鐨勬帴鍙o紝瀹冪殑鐪熸瀹炵幇鏄湪Implement綾婚噷闈?鑰岃繖涓粎浠呮槸鎺ュ彛"浠g悊"
RE_TYPE Interface_FOO()
{
return lpImplementInstance->FOO
_
Implementation(); //鍙ユ焺浠g悊璋冪敤瀹炵幇鐪熸鐨凢OO鎺ュ彛
}
//榪樻湁鍏朵粬鐨勬帴鍙d篃涓鏍鳳紝鍧囨槸鐢ㄥ彞鏌勭被浠g悊鎺ュ彛
//....
private:
Implement * lpImplementInstance; //榪欎釜鏄彞鏌勭被鍞竴鐨勬暟鎹垚鍛?褰撶劧錛屽茍涓嶄竴瀹?,鍙互琚彞鏌勭被寰堝ソ鍦拌嚜鍔ㄧ鐞?br>};




  琚皝瑁呭湪鍙ユ焺綾婚噷闈㈢殑鐪熸瀹炵幇錛坈lass Implement錛夊皢涓庣敤鎴烽殧紱誨紑鏉ワ紝灝辨槸璇達紝灝辯畻浠ュ悗Implement 綾葷殑瀹炵幇鏈夋墍鏀瑰彉錛?br>鍙瀹冩彁渚涚殑鎺ュ彛涓嶅彉錛岄偅涔堝畠鐨勫彞鏌勭被灝變笉浼氭敼鍙橈紝鑰屽寘鍚彞鏌勭被鐨勭敤鎴鳳紝涔熶笉鐢ㄥ仛浠諱綍鐩稿簲鐨勬敼鍙橈紙鎵鏈夊寘鍚?“Handle.h”鐨勬ā鍧楃敋鑷充笉鐢ㄤ粠鏂扮紪璇戝氨鍙互姝e父鏇存柊鑷蟲渶鏂扮殑Implement瀹炵幇錛夈?br>
渚嬪
#include "Handle.h"
Imlementhandle testhandle;
testhandle->Interface_Foo();//璋冪敤鎺ュ彛鍗沖彲銆?br> 濡傛灉鏀瑰姩浜咺mplent綾葷殑鏂規硶

  浜庢鐩稿弽錛屽鏋滅洿鎺ョ敤class Implement 鐨勫畾涔夛紝閭d箞鍙Implement綾葷殑瀹氫箟鏈夋墍鏀瑰彉錛堜笉綆℃槸public 榪樻槸private 鎴愬憳
鐨勬洿鏂幫級錛岄偅涔堟墍鏈夊寘鍚畠鐨勫ご鏂囦歡鐨勬ā鍧楅兘瑕佷粠鏂扮紪璇戜竴嬈°?br>
榪欏叾瀹炲氨鏄帴鍙d笌瀹炵幇鐨勫垎紱伙紝




]]>
C++瀹炵幇璁捐妯″紡涓殑Interface from goolgehttp://www.shnenglu.com/michaelgao/archive/2008/10/07/63392.htmlmicheal's techmicheal's techTue, 07 Oct 2008 06:39:00 GMThttp://www.shnenglu.com/michaelgao/archive/2008/10/07/63392.htmlhttp://www.shnenglu.com/michaelgao/comments/63392.htmlhttp://www.shnenglu.com/michaelgao/archive/2008/10/07/63392.html#Feedback0http://www.shnenglu.com/michaelgao/comments/commentRss/63392.htmlhttp://www.shnenglu.com/michaelgao/services/trackbacks/63392.htmlInterface suffix.
link

Definition:

A class is a pure interface if it meets the following requirements:

  • It has only public pure virtual ("= 0") methods and static methods (but see below for destructor).
  • It may not have non-static data members.
  • It need not have any constructors defined. If a constructor is provided, it must take no arguments and it must be protected.
  • If it is a subclass, it may only be derived from classes that satisfy these conditions and are tagged with the Interface suffix.

An interface class can never be directly instantiated because of the pure virtual method(s) it declares. To make sure all implementations of the interface can be destroyed correctly, they must also declare a virtual destructor (in an exception to the first rule, this should not be pure). See Stroustrup, The C++ Programming Language, 3rd edition, section 12.4 for details.

Pros: Tagging a class with the Interface suffix lets others know that they must not add implemented methods or non static data members. This is particularly important in the case of multiple inheritance. Additionally, the interface concept is already well-understood by Java programmers.

Cons: The Interface suffix lengthens the class name, which can make it harder to read and understand. Also, the interface property may be considered an implementation detail that shouldn't be exposed to clients.

Decision: A class may end with Interface only if it meets the above requirements. We do not require the converse, however: classes that meet the above requirements are not required to end with Interface.




]]>
久久国产精品免费| 青草影院天堂男人久久| 亚洲国产成人精品女人久久久 | 99久久成人18免费网站| 久久精品这里只有精99品| 久久国语露脸国产精品电影| 久久ZYZ资源站无码中文动漫| 97久久精品人人澡人人爽| 久久精品综合网| 91久久精品国产91性色也| 久久午夜夜伦鲁鲁片免费无码影视| 99久久精品午夜一区二区| 久久久这里只有精品加勒比| 国产精品久久永久免费| 99蜜桃臀久久久欧美精品网站 | 久久精品国产免费一区| 亚洲国产精品无码久久青草| 久久精品亚洲中文字幕无码麻豆| 久久久久久极精品久久久| 99久久99这里只有免费费精品| 亚洲国产视频久久| 久久精品无码免费不卡| 激情伊人五月天久久综合| 亚洲精品无码久久久久sm| 无码乱码观看精品久久| 久久久久久青草大香综合精品| 99热成人精品热久久669| 久久久久久九九99精品| 久久精品国产亚洲av麻豆小说| 无码8090精品久久一区| 青青久久精品国产免费看| 久久这里有精品视频| 久久久久无码精品国产app| 国产午夜福利精品久久| 久久婷婷国产麻豆91天堂| 国产精品久久亚洲不卡动漫| .精品久久久麻豆国产精品| 99久久成人国产精品免费| 成人久久综合网| 精品国产婷婷久久久| 久久经典免费视频|