C ++ design mode

xiaoxiao2021-03-06  109

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 copied from the VC:

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 : Simplified Abnormal Security Code", original from http://www.cuj.com/experts/1812/alexandr.htm?topic=experts, Chinese translation from "C " VIEW No. 5. The article is absolutely first-class, and the Adaptor mode is also used in the code given, and there is also a representative. I generalize it, summarize the following example:

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 void test (t) {T.Proc ();} is really good, but this only applies to simple situations, sometimes it is very complicated, such as we can't put the type in the template parameter!

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 class adaptor: public odaptor, private t // Implement inheritance {public: Virtual Void Proc ( ) {T :: proc ();}}; // Call the function proc in a unified manner, instead of concern is T1, T2 or other Void Test (const std :: auto_ptr

& 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 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 {};} client code {using namespace DesignPattern_Singleton; ConcreteSingleton * p = ConcreteSingleton :: Instance ();} C Mode Development Bridge2002-07-29 · · · COM concentration camp, the function separates the abstraction section to its implementation part, so that they can change independently. Second, structural map three, sample code

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 class ConcreteCreator: public Creator {public: virtual Product * CreateProduct () {return new ConcreteProduct ();}}; the nature of the template and inheritance One of the differences: Template: behavior does not depend on the type. Inherit: behavior depends on the type. (Effective C Item 41) In fact, there is a case where the template can be replaced in many modes, which is consistent with the behavior of subclasses. Fourth, the sample code namespace DesignPattern_FactoryMethod {class Product {/*...*/}; class ConcreteProduct: public Product {/*...*/}; // class Creatorclass Creator {public: virtual Product * CreateProduct () = 0 void Operate ();}; void creator :: Operate () {// ... product * p = createproduct (); // ...} // Class ConcretecreatorClass Concretecreator: public create {public: Virtual Product * CreateProduct () {Return New ConcreteProduct ();}};} Client code: {Using Namespace DesignPattern_FactoryMethod; Concretecreator P; p. ga, the createproduct is actually a Template Method. 5. The application of instance factory method is too wide, it is often used in other modes, and in fact, in fact, inventory. (1) The CDocument class in the MFC contains three functions similar to the above figure CAPPLICATION. The CreateDocument here is a Factory Method because it is responsible for creating a document object. (2) When a class delegates its responsibilities to an independent class, it produces a parallel class level. The figure and manipulator in the above figure are parallel levels, and Figure represents some graphical elements, such as lines, text, etc., and Manipulator represents operations that act on these graphic elements, such as drag, move, and select. If the status information required for these operations does not need to be saved in Figure, it is a good idea to divide the figure and manipulator into two classes. The CreateManipulator here is a Factory Method.

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 (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 (p); if (pc2 == null) Return; // DO Add Operation} Class Concreteleaf1: Public AbstractLeaf1 {Public: Virtual Void Operation () {/ * do Oper ation * /}}; class ConcreteLeaf2: public AbstractLeaf1, public AbstractLeaf2 {public: virtual void operation () {/ * do operation * /}};} client code: {using namespace DesignPattern_Composite; Component * pc1 = new ConcreteLeaf1 () Component * pc2 = new contRteleaf2 (); Component * pc3 = new composite11 (); Component * PC4 = new composite2 (); pc3-> add (pc1); // okpc3-> add (pc2); // okpc3- > Add (pc3); // okpc3-> add (pc4); // failpc4-> add (pc1); // failpc4-> add (pc2); // okpc4-> add (pc3); // failPC4- > Add (pc4); // ok} There are two points to note, because it is used to inherit, so you need to use Virtual Inheritance. The second is to use Dynamic_CAST to determine if the component is allowed. V. Sample code

转载请注明原文地址:https://www.9cbs.com/read-101102.html

New Post(0)