C design mode adapter2002-08-06 · · · · COM concentration
First, function
Convert a class interface into another interface that customers want, solve the problem of mismatch between two existing interfaces. Adapter mode makes it possible to work with those classes that are not compatible with interfaces.
Second, the structure map (1) Class Adapter
(2) Object Adapter
Third, the implementation and other many modes, the focus of learning design model is to learn the idea of each mode, and should not be stabilized in some specific structural map and implementation. Because the mode is flexible, it can be a thousand variable, but the so-called change is not from its Zong. A large amount of Adapter mode is used in STL, like Function Adapter, Iterator Adpter, which is not the same as the Adapter structure here, but the thoughts are the same. Specific introduction can go to Houjie website to find related articles, he is very good.
Fourth, sample code (1) Class Adapter
namespace DesignPattern_Adapter {// class Adapteeclass Adaptee {public: void SpecialRequest () {}}; // class Targetclass Target {public: virtual void Request () = 0;}; // class Adapterclass Adapter: public Target, private Adaptee {public : Virtual void request () {specialRequest ();}};} client code: {usingspace design; type; p-> request (); // actually call Adapte :: SpecialRequest ()}
(2) Object Adapter Namespace DesignPattern_Adapter
{// class Adapteeclass Adaptee {public: void SpecialRequest () {}}; // class Targetclass Target {public: virtual void Request () = 0;}; // class Adapterclass Adapter: public Target {public: virtual void Request ( ) {_adaptee.specialRequest ();} private: adaptee _adaptee;};} client code: {using namespace design: {using namespace designpattern_adapter; target * p = new adapter (); p-> request (); // actually call Adaptee :: SpecialRequest ()}
Six, instances (1) Class Adapter in STL
Adapter Class in STL includes: a.stack (corresponding Adaptee is Deque). B.Queue (the corresponding Adaptee is Deque). C.Priority_Queue (the corresponding Adaptee is vector). Below is the class definition of the class definition from
Template
Class _Container = Deque <_ty>>
Class Stack
{// Lifo Queue Implement with a Container
PUBLIC:
Typedef _Container Container_Type;
TypeDef TypeName_Type Value_Type; TypeDef TypeName_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 emptyreturn ( C.empty ());} size_type size () const {// test length of stackreturn (c.size ());} value_type & top () {// Return Last Element of Mutable StackReturn (C.Back ()); } const value_type & top () const {// return Last Element of nonmutable stackreturn (c.back ());} void push (const value_type&val) {// INSERT Element at endc.push_back (_val);} void pop () {// ERASE Last Elementc.pop_back ();} Bool_eq (const stack <_ty, _container> & _right) const {// test for stack equalityreturn (c == _right.c);} BOOL _LT (Const Stack <_ty _Container> & _right) const {// test if this <_right for stacksreturn (c <_right.c);} protected: _container c; // the underlying container};
The key is _Container C, all of the Stack all operations are transferred to C to process. (This is actually the "Object Adapter" mentioned earlier, pay attention to the Class Adapter in STL and the incomplete Class Adapter concept described above) Stack's method is simple, as follows:
{INT IA [] = {1, 3, 2, 4}; Deque
ID (IA, IA 4);
Stack
IS (ID);
}
(2) Recently, I have seen an article "Generic
Question: Assume that there are several classes, they have some common behaviors, but they are independent (no common base classes). Such as:
Class T1 {public: void proc () {}}; class t2 {public: void proc () {}}; // ...
How to call these behaviors in a unified way?
Solution 1: It will be very natural, you will think of template, such as:
Template
Workaround 2: Difficulties come from these classes without a common base class, so we create a base class and then Adapt.
// Class Iadaptor, abstract base class class adaptor {public: Virtual void proc () = 0;}; // Class Adaptortemplate
& SP)
{
SP-> proc ();
}
Client code:
TEST (std :: auto_ptr
(
New Adaptor
));
TEST (std :: auto_ptr
(
New Adaptor
));
The above example is very simple, and the template function in the method can be solved very well. Here is a slightly complicated example, create an appropriate object according to the parameter type:
Class T1 {public: T1 (int) {/ *...*/} void proc () {/ / {/ {/ {/}; Class T2 {public: T2 (char) {/*...// } void proc () {/ *...*/}}; // Class Iadaptor, abstract base class class ipaptor {public: virtual void proc () = 0;}; // Class AdapTortemplate
Class Adaptor: Public Iadaptor, Private T // Implement inheritance
{
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;
}
Client code: Test T1 (10); T1.Proc (); Test T2 ('c'); t2.proc ();
The above is an example rather than an example, you may be more willing to see its actual use. Go to download the author written by the author, enjoy it.
C Design Mode Abstract Factory2002-07-23 · ···· COM concentration camp, function provides an interface to create a series of associated or interdependent objects without specifying their specific classes. Second, the most basic structural diagram of the structural map class is as follows: In practical applications, class plant mode can be expanded to a complicated situation, as shown in the following figure: Third, the advantages and disadvantages: (1) Package creation process. Customers don't know how the class is created, and the class is closed all created details. This can choose a different creative method, adding flexibility. (2) isolation of customers with specific classes and improve their reusability. Disadvantages: The Factory class level is usually parallel to the specific class level (ie, one or one correspond). Increase a specific class, generally adding a Factory class accordingly, increasing system complexity. Fourth, implementation (1) The Abstract Factory class is usually a collection of Factory Method. Personally think that there is no essential difference with Factory Method mode. (2) The plant can usually use the plant as a single piece.
V. Sample Code 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; // Create ProductA virtual AbstractProductB * CreateProductB () = 0; // Create 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 contradefactory2: 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 &);};} client code: {using namespace DesignPattern_AbstractFactory; // The first method of creating AbstractFactory * pFactory = ConcreteFactory1 :: Instance (); AbstractProductA * pproducta = pfactory-> createproducta (); abstractProductB * pproductb = pfactory-> createproductb ();
// Second creation method Pfactory = concretefactory2 :: instance (); pproducta = pfactory-> createproducta (); pproductb = pfactory-> createproductb ();} 6. The first day of understanding is in COM, but I didn't expect this that this is a model that can be used in many other modes. Components cannot be created directly in COM, which is also determined by a characteristic of COM: that is, the customer doesn't know the class name of the component to be created. C Design Mode Singleton2002-07-26 · · ··· COM concentration camp, function guarantees that only one instance is only one instance. Second, the structure Figure 3, the advantages and disadvantages Singleton mode is the alternative to "global variable". Therefore, it has the characteristics of global variables: globally, throughout the entire life of the application, it also has the nature of global variables: the same type of object instance may only have one. Fourth, the Singleton, which realizes the textbook, is as follows:
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 InitializationReturn_INSTANCE;} (1) Because the returned pointer, to prevent users from calling the delete function, Change Static Singleton * _Instance; define Static Singleton_INSTANCE in Instance (). This is clearly safer, and also has the characteristics of Lazy Initialization (creating first access). (2) Assumptions need to be derived from Singleton, while subclasses also need to have the same nature, only one instance can be created. I think this is very difficult. The root cause is that the instance () function is not a virtual function, does not have a polymorphic nature. One common method is to move the instance () function into the subclass, then you can only use Static Singleton * _Instance, not to use Static Singleton _instance, unless _Instance is also moved to the subclass, no matter how Not elegant. Another method is to use a template. What method is specifically used, it can only be balanced according to the actual situation. V. Sample code (1) There is no subclass
namespace DesignPattern_Singleton {class Singleton {public: static Singleton * Instance () {static Singleton _instance; return & _instance;} protected: Singleton () {} private: Singleton (const Singleton &); Singleton & operator = (const Singleton &);};} Client End code: {Using Namespace DesignPattern_singleton; Singleton * P = Singleton :: Instance (); ...} (2) Sub-class
Method a: namespace DesignPattern_Singleton {// class Singletonclass Singleton {protected: Singleton () {} static Singleton * _instance; private: Singleton (const Singleton &); Singleton & operator = (const Singleton &);}; Singleton * Singleton :: _ instance = NULL ; // class ConcreteSingletonclass ConcreteSingleton: public Singleton {public: static Singleton * instance (); protected: ConcreteSingleton () {}};? Singleton * ConcreteSingleton :: instance () {(_ instance == NULL) _instance = new ConcreteSingleton () : 0; return _instance;}} client code: {using namespace DesignPattern_Singleton; Singleton * p = ConcreteSingleton :: Instance ();} method two: namespace DesignPattern_Singleton {// class Singletonclass Singleton {protected: Singleton () {} private: singleton (const singleton &); singleton & operator = (const singleton &);}; // class ConcreteSingletonclass ConcreteSingleton: public singleton {public: static singleton * Instance () {static ConcreteSingleton _instance; return & _instance;} protected: ConcreteSingleton () {}} Client code: {USIN g namespace DesignPattern_Singleton; Singleton * p = ConcreteSingleton :: Instance ();} Method three: namespace DesignPattern_Singleton {template
namespace DesignPattern_Bridge {// class Implementorclass Implementor {public: virtual void OperationImp () = 0;}; // class ConcreteImplementorAclass ConcreteImplementorA: public Implementor {public: virtual void OperationImp () {}}; // class ConcreteImplementorBclass ConcreteImplementorB: public Implementor { PUBLIC: Virtual Void OperationImp () {}}; // Class AbstractClass Abstract {Public: Void Operation (Implementor * IMP) {Assert (IMP); IMP-> OperationImp ();}};} client code: {using namespace DesignPattern_Bridge; Abstract Obj; Implementor * IMPA = New Concreteimplementora (); Implementor * IMPB = New ConcreteImPlementorb (); Obj.Operation (IMPA); // First implementation method OBJ.Operation (IMPB); // Second implementation Method} IV (1) Create a window that can be used in the Presentation Manager system of X Window System and IBM. (Examples in the book) Bridge's charm is a loose relationship between abstraction and implementation, which can be combined between them. As in the above figure, there is four combinations of IconWindow XWindowImp, TransientWindow XWindowImp, TransientWindow PMWindowIMP.
C mode Designed Builder2002-07-30 · · · COM concentration camp, the function separates the construction of a complex object with its representation, so that the same build process can create different representations. Second, the interaction between various types of structures is shown in the following figure: 3, sample code
Namespace designpattern_builder {class product1 {/ *...*/}; class product2 {/ *...*/}; // Class BuilderClass Builder // Abstract class {public: Virtual void builderParta () {} // provides The default implementation virtual void BuilderPartB () {} virtual void BuilderPartC () {} protected: Builder () {}}; // class ConcreteBuilder1class ConcreteBuilder1: public Builder // Create Product1 {public: ConcreteBuilder1 (): _product (NULL) { } Virtual void builderparta () {/ *...*/} Virtual void builderpartb () {/ *...*/} Virtual void builderpartc () {/ *...*/} Virtual product1 * getProduct1 () { return _product;} // returns Product1 private objects created: Product1 * _product;}; // class ConcreteBuilder2class ConcreteBuilder2: public Builder // Create Product2 {public: ConcreteBuilder2 (): _product (NULL) {} virtual void BuilderPartA () { /*...*/} Virtual void builderpartb () {/*...*/} Virtual void builderpartc () {/*...*/} Virtual product2 * getProduct2 () {return_product;} // Return Created Product2 Object Private: Product2 * _Product;}; // Class DirectorClass Director {public: // Create an object (Dire Ctor does not know what the specific creation is like, only the client that calls the function knows) Void Construct (Builder * Builder) {Builder-> BuilderParta (); builder-> builderpartb (); builder-> builderpartc () ;}};} client code: {using namespace DesignPattern_Builder; Director director; // Create a first target ConcreteBuilder1 * pBuilder1 = new ConcreteBuilder1 (); director.Construct (pBuilder1); Product1 * product1 = pBuilder1-> GetProduct1 () ; // Create a second object Concretebuilder2 * pbuilder2 = new concretebuilder2 (); Director.Construct (pbuilder2); product2 * product2 = pbuilder2-> getProduct2 ();} four, instance (1) example one. As shown in the figure below: The function above the figure is to convert an RTF file into a variety of body formats. RTFReader performs grammatical analysis and then converts all TOKEN strings. It can be seen that Builder is to assemble each part into a whole step. It encloses the method of assembly, and the assembled object is also large.
Prototype2002-08-01 · · ·············································································· Second, structural map three, advantages and disadvantages: copy itself. Customers don't know the actual type of objects, just know that it's abstract base class. (Ie the situation of inherited trees) Disadvantages: You must have an object instance (ie, prototype) to clone. Fourth, the sample code namespace DesignPattern_Prototype {// class Prototypeclass Prototype // abstract base class {public: virtual Prototype * Clone () = 0;}; // class ConcretePrototype1class ConcretePrototype1: public Prototype {public: virtual Prototype * Clone () {ConcretePrototype1 * p = new ConcretePrototype1 (); * p = * this; // copy target return p;}}; // class ConcretePrototype2class ConcretePrototype2: public Prototype {public: virtual Prototype * Clone () {ConcretePrototype2 * p = new ConcretePrototype2 () ; * p = * this; // copy target return p;}};} client code: {using namespace DesignPattern_Prototype; ConcretePrototype1 * obj1 = new ConcretePrototype1 (); // prototype object 1ConcretePrototype2 * obj2 = new ConcretePrototype2 (); / / Prototype object 2 prototype * newobj1 = obj1-> clone (); // Clone object 1PrototyPE * newobj2 = Obj2-> clone (); // Clone object 2 // use copied object newobj1 and newobj2} 5, instance In a graphic editor, each graphic element, such as line, circle, text, etc., should support copy operation, namely, graphics, press CTRL C, and then press CTRL V to copy a new graphic. Obviously this is a CLONE operation. So in each of the graphic subclasses derived from Graphic, PROTOTYPE mode should be used, plus Clone operations.
C design mode Factory method2002-08-05 · · ··· COM concentration camp, function defines an interface for creating an object, allowing subclasses to instantize which class. Factory Method delays a class of instantiation to their subclasses. Second, Structure Figure 3, implementation (1) In some cases, such as derived a new Creator subclass in order to create an appropriate Product object, and create a template instead of inheritance when creating a different product method. Such as:
class Creator {public: virtual Product * CreateProduct () = 0;}; template
C design mode Composite2002-08-06 · · · COM concentration camp 1. Function represents "Part-Overall" relationship, and uses a single object and combination object using a consistent manner. Second, in the figure above map, some extensions can also be done, and LEAF and Composite can be made as abstract base classes as needed, which is sent from the child. Third, the advantages of advantages and disadvantages: For Composite mode, perhaps the attention of people will focus on how it implements combined objects. However, Composite is most important that users don't care whether combined object or a single object, the user will process in a unified manner, so the base class should be a common interface proposed from a single object and a combined object. Disadvantages: The biggest problem with Composite is to limit the components in the combination. 4. Implementing the components that sometimes need to limit the combination, that is, I hope that a Composite can only have certain LEAFs. I am solved with multiple inheritance and dynamic type conversion. If the combination object Composite1 can only include a single object ConcretEleaf1, Composite2 can include a single object ConcretEleaf1 and ConcretEleaf2. As shown in the figure below: The class hierarchy in the above picture is more, using AbstractLeaf1 and AbstractLeaf2, but did not use AbstractCompositive11 and AbstractComposite2, this is not important, you can also remove AbstractLeaf1 and AbstractLeaf2, this is not important, you can determine according to specific conditions Do you want. The simple code is implemented as follows:
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