源于Design Pattern Explanation with C++ Implementation的 设计模式 C++

1、创建型模式 (Creational Pattern)
1.1 工厂模式(Factory Pattern )
1.2  抽象工厂模式(Abstract Factory Pattern )
1.3  单例模式(Singleton Pattern )
1.4  建造者模式(Builder Pattern )

1.5  原型模式(Prototype Pattern )

1.6  简单工厂模式(Simple Factory Pattern)


2、结构型模式(Structural Pattern)
2.1 桥梁模式(Bridge Pattern )
2.2 适配器模式(Adapter Pattern )
2.3 装饰模式(Decorator Pattern )
2.4 合成模式 (Composite Pattern )
2.5 享元模式(Flyweight Pattern )
2.6 门面模式(Facade Pattern )
2.7 代理模式(Proxy Pattern )


3、行为模式(Behavioral Pattern )
3.1 模板模式(Template Pattern )
3.2 策略模式(Strategy Pattern )
3.3 状态模式(State Pattern)
3.4 观察者模式(Observer Pattern )
3.5 备忘录模式(Memento Pattern)
3.6 中介者模式(Mediator Pattern)
3.7 命令模式(Command Pattern )
3.8 访问者模式(Visitor Pattern )
3.9 责任链模式(Chain of Responsibility Pattern )
3.10 迭代器模式(Iterator Pattern )
3.11 解析器模式(Interpreter Pattern )


参考     http://www.cnblogs.com/zhenyulu/articles/79894.html

参考    http://www.cnblogs.com/chengxingliang/category/306506.html


https://en.wikibooks.org/wiki/C%2B%2B_Programming/Code/Design_Patterns


Programming Patterns[edit]

Software design patterns are abstractions that help structure system designs. While not new, since the concept was already described by Christopher Alexander in its architectural theories, it only gathered some traction in programming due to the publication of Design Patterns: Elements of Reusable Object-Oriented Software book in October 1994 by Erich GammaRichard HelmRalph Johnson and John Vlissides, known as the Gang of Four (GoF), that identifies and describes 23 classic software design patterns.

A design pattern is neither a static solution, nor is it an algorithm. A pattern is a way to describe and address by name (mostly a simplistic description of its goal), a repeatable solution or approach to a common design problem, that is, a common way to solve a generic problem (how generic or complex, depends on how restricted the target goal is). Patterns can emerge on their own or by design. This is why design patterns are useful as an abstraction over the implementation and a help at design stage. With this concept, an easier way to facilitate communication over a design choice as normalization technique is given so that every person can share the design concept.

Depending on the design problem they address, design patterns can be classified in different categories, of which the main categories are:

Patterns are commonly found in objected-oriented programming languages like C++ or Java. They can be seen as a template for how to solve a problem that occurs in many different situations or applications. It is not code reuse, as it usually does not specify code, but code can be easily created from a design pattern. Object-oriented design patterns typically show relationships and interactions between classes or objects without specifying the final application classes or objects that are involved.

Each design pattern consists of the following parts:

Problem/requirement 
To use a design pattern, we need to go through a mini analysis design that may be coded to test out the solution. This section states the requirements of the problem we want to solve. This is usually a common problem that will occur in more than one application.
Forces 
This section states the technological boundaries, that helps and guides the creation of the solution.
Solution 
This section describes how to write the code to solve the above problem. This is the design part of the design pattern. It may contain class diagrams, sequence diagrams, and or whatever is needed to describe how to code the solution.

Design patterns can be considered as a standardization of commonly agreed best practices to solve specific design problems. One should understand them as a way to implement good design patterns within applications. Doing so will reduce the use of inefficient and obscure solutions[citation needed]. Using design patterns speeds up your design and helps to communicate it to other programmers[citation needed].

Creational Patterns[edit]

In software engineeringcreational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.

In this section of the book we assume that the reader has enough familiarity with functions, global variables, stack vs. heap, classes, pointers, and static member functions as introduced before.

As we will see there are several creational design patterns, and all will deal with a specific implementation task, that will create a higher level of abstraction to the code base, we will now cover each one.

Builder[edit]

The Builder Creational Pattern is used to separate the construction of a complex object from its representation so that the same construction process can create different objects representations.

Problem 
We want to construct a complex object, however we do not want to have a complex constructor member or one that would need many arguments.
Solution 
Define an intermediate object whose member functions define the desired object part by part before the object is available to the client. Builder Pattern lets us defer the construction of the object until all the options for creation have been specified.
#include <string>
#include <iostream>
#include <memory>
using namespace std;

// "Product"
class Pizza
{
    
public:
	void setDough(const string& dough)
	{
    
		m_dough = dough;
	}
	void setSauce(const string& sauce)
	{
    
		m_sauce = sauce;
	}
	void setTopping(const string& topping)
	{
    
		m_topping = topping;
	}
	void open() const
	{
    
		cout << "Pizza with " << m_dough << " dough, " << m_sauce << " sauce and "
			<< m_topping << " topping. Mmm." << endl;
	}
private:
	string m_dough;
	string m_sauce;
	string m_topping;
};

// "Abstract Builder"
class PizzaBuilder
{
    
public:
	virtual ~PizzaBuilder() {};

	Pizza* getPizza()
	{
    
		return m_pizza.release();
	}
	void createNewPizzaProduct()
	{
    
		m_pizza = make_unique<Pizza>();
	}
	virtual void buildDough() = 0;
	virtual void buildSauce() = 0;
	virtual void buildTopping() = 0;
protected:
	unique_ptr<Pizza> m_pizza;
};

//----------------------------------------------------------------

class HawaiianPizzaBuilder : public PizzaBuilder
{
    
public:
	virtual ~HawaiianPizzaBuilder() {};

	virtual void buildDough()
	{
    
		m_pizza->setDough("cross");
	}
	virtual void buildSauce()
	{
    
		m_pizza->setSauce("mild");
	}
	virtual void buildTopping()
	{
    
		m_pizza->setTopping("ham+pineapple");
	}
};

class SpicyPizzaBuilder : public PizzaBuilder
{
    
public:
	virtual ~SpicyPizzaBuilder() {};

	virtual void buildDough()
	{
    
		m_pizza->setDough("pan baked");
	}
	virtual void buildSauce()
	{
    
		m_pizza->setSauce("hot");
	}
	virtual void buildTopping()
	{
    
		m_pizza->setTopping("pepperoni+salami");
	}
};

//----------------------------------------------------------------

class Cook
{
    
public:
	void openPizza()
	{
    
		m_pizzaBuilder->getPizza()->open();
	}
	void makePizza(PizzaBuilder* pb)
	{
    
		m_pizzaBuilder = pb;
		m_pizzaBuilder->createNewPizzaProduct();
		m_pizzaBuilder->buildDough();
		m_pizzaBuilder->buildSauce();
		m_pizzaBuilder->buildTopping();
	}
private:
	PizzaBuilder* m_pizzaBuilder;
};

int main()
{
    
	Cook cook;
	HawaiianPizzaBuilder hawaiianPizzaBuilder;
	SpicyPizzaBuilder    spicyPizzaBuilder;

	cook.makePizza(&hawaiianPizzaBuilder);
	cook.openPizza();

	cook.makePizza(&spicyPizzaBuilder);
	cook.openPizza();
}
Factory[edit]

Definition: A utility class that creates an instance of a class from a family of derived classes

Abstract Factory[edit]

Definition: A utility class that creates an instance of several families of classes. It can also return a factory for a certain group.


The Factory Design Pattern is useful in a situation that requires the creation of many different types of objects, all derived from a common base type. The Factory Method defines a method for creating the objects, which subclasses can then override to specify the derived type that will be created. Thus, at run time, the Factory Method can be passed a description of a desired object (e.g., a string read from user input) and return a base class pointer to a new instance of that object. The pattern works best when a well-designed interface is used for the base class, so there is no need to cast the returned object.

Problem 
We want to decide at run time what object is to be created based on some configuration or application parameter. When we write the code, we do not know what class should be instantiated.
Solution 
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

In the following example, a factory method is used to create laptop or desktop computer objects at run time.

Let's start by defining Computer, which is an abstract base class (interface) and its derived classes: Laptop and Desktop.

 class Computer
 {
    
 public:
     virtual void Run() = 0;
     virtual void Stop() = 0;
     
     virtual ~Computer() {}; /* without this, you do not call Laptop or Desktop destructor in this example! */
 };
 class Laptop: public Computer
 {
    
 public:
     void Run() override {
    mHibernating = false;}; 
     void Stop() override {
    mHibernating = true;}; 
     virtual ~Laptop() {}; /* because we have virtual functions, we need virtual destructor */
 private:
     bool mHibernating; // Whether or not the machine is hibernating
 };
 class Desktop: public Computer
 {
    
 public:
     void Run() override {
    mOn = true;}; 
     void Stop() override {
    mOn = false;}; 
     virtual ~Desktop() {};
 private:
     bool mOn; // Whether or not the machine has been turned on
 };

The actual ComputerFactory class returns a Computer, given a real world description of the object.

 class ComputerFactory
 {
    
 public:
     static Computer *NewComputer(const std::string &description)
     {
    
         if(description == "laptop")
             return new Laptop;
         if(description == "desktop")
             return new Desktop;
         return NULL;
     }
 };

Let's analyze the benefits of this design. First, there is a compilation benefit. If we move the interface Computer into a separate header file with the factory, we can then move the implementation of the NewComputer() function into a separate implementation file. Now the implementation file for NewComputer()is the only one that requires knowledge of the derived classes. Thus, if a change is made to any derived class of Computer, or a new Computer subtype is added, the implementation file for NewComputer() is the only file that needs to be recompiled. Everyone who uses the factory will only care about the interface, which should remain consistent throughout the life of the application.

Also, if there is a need to add a class, and the user is requesting objects through a user interface, no code calling the factory may be required to change to support the additional computer type. The code using the factory would simply pass on the new string to the factory, and allow the factory to handle the new types entirely.

Imagine programming a video game, where you would like to add new types of enemies in the future, each of which has different AI functions and can update differently. By using a factory method, the controller of the program can call to the factory to create the enemies, without any dependency or knowledge of the actual types of enemies. Now, future developers can create new enemies, with new AI controls and new drawing member functions, add it to the factory, and create a level which calls the factory, asking for the enemies by name. Combine this method with an XML description of levels, and developers could create new levels without having to recompile their program. All this, thanks to the separation of creation of objects from the usage of objects.

Another example:

#include <stdexcept>
#include <iostream>
#include <memory>
using namespace std;

class Pizza {
    
public:
	virtual int getPrice() const = 0;
	virtual ~Pizza() {};  /* without this, no destructor for derived Pizza's will be called. */
};

class HamAndMushroomPizza : public Pizza {
    
public:
	virtual int getPrice() const {
     return 850; };
	virtual ~HamAndMushroomPizza() {};
};

class DeluxePizza : public Pizza {
    
public:
	virtual int getPrice() const {
     return 1050; };
	virtual ~DeluxePizza() {};
};

class HawaiianPizza : public Pizza {
    
public:
	virtual int getPrice() const {
     return 1150; };
	virtual ~HawaiianPizza() {};
};

class PizzaFactory {
    
public:
	enum PizzaType {
    
		HamMushroom,
		Deluxe,
		Hawaiian
	};

	static unique_ptr<Pizza> createPizza(PizzaType pizzaType) {
    
		switch (pizzaType) {
    
		case HamMushroom: return make_unique<HamAndMushroomPizza>();
		case Deluxe:      return make_unique<DeluxePizza>();
		case Hawaiian:    return make_unique<HawaiianPizza>();
		}
		throw "invalid pizza type.";
	}
};

/*
* Create all available pizzas and print their prices
*/
void pizza_information(PizzaFactory::PizzaType pizzatype)
{
    
	unique_ptr<Pizza> pizza = PizzaFactory::createPizza(pizzatype);
	cout << "Price of " << pizzatype << " is " << pizza->getPrice() << std::endl;
}

int main()
{
    
	pizza_information(PizzaFactory::HamMushroom);
	pizza_information(PizzaFactory::Deluxe);
	pizza_information(PizzaFactory::Hawaiian);
}
Prototype[edit]

A prototype pattern is used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used, for example, when the inherent cost of creating a new object in the standard way (e.g., using the new keyword) is prohibitively expensive for a given application.

Implementation: Declare an abstract base class that specifies a pure virtual clone() method. Any class that needs a "polymorphic constructor" capability derives itself from the abstract base class, and implements the clone() operation.

Here the client code first invokes the factory method. This factory method, depending on the parameter, finds out the concrete class. On this concrete class, the clone() method is called and the object is returned by the factory method.

  • This is a sample implementation of Prototype method. We have the detailed description of all the components here.
    • Record class, which is a pure virtual class that has a pure virtual method clone().
    • CarRecordBikeRecord and PersonRecord as concrete implementation of a Record class.
    • An enum RecordType as one to one mapping of each concrete implementation of Record class.
    • RecordFactory class that has a Factory method CreateRecord(…). This method requires an enum RecordType as parameter and depending on this parameter it returns the concrete implementation of Record class.
/** Implementation of Prototype Method **/
#include <iostream>
#include <unordered_map>
#include <string>
#include <memory>
using namespace std;


/** Record is the base Prototype */
class Record
{
    
public:
	virtual ~Record() {}
	virtual void print() = 0;
	virtual unique_ptr<Record> clone() = 0;
};

/** CarRecord is a Concrete Prototype */
class CarRecord : public Record
{
    
private:
	string m_carName;
	int m_ID;

public:
	CarRecord(string carName, int ID) : m_carName(carName), m_ID(ID)
	{
    
	}

	void print() override
	{
    
		cout << "Car Record" << endl
		     << "Name  : "   << m_carName << endl
		     << "Number: "   << m_ID << endl << endl;
	}

	unique_ptr<Record> clone() override
	{
    
		return make_unique<CarRecord>(*this);
	}
};

/** BikeRecord is the Concrete Prototype */
class BikeRecord : public Record
{
    
private:
	string m_bikeName;
	int m_ID;

public:
	BikeRecord(string bikeName, int ID) : m_bikeName(bikeName), m_ID(ID)
	{
    
	}

	void print() override
	{
    
		cout << "Bike Record" << endl
		     << "Name  : " << m_bikeName << endl
		     << "Number: " << m_ID << endl << endl;
	}

	unique_ptr<Record> clone() override
	{
    
		return make_unique<BikeRecord>(*this);
	}
};


/** PersonRecord is the Concrete Prototype */
class PersonRecord : public Record
{
    
private:
	string m_personName;
	int m_age;

public:
	PersonRecord(string personName, int age) : m_personName(personName), m_age(age)
	{
    
	}

	void print() override
	{
    
		cout << "Person Record" << endl
			<< "Name : " << m_personName << endl
			<< "Age  : " << m_age << endl << endl;
	}

	unique_ptr<Record> clone() override
	{
    
		return make_unique<PersonRecord>(*this);
	}
};


/** Opaque record type, avoids exposing concrete implementations */
enum RecordType
{
    
	CAR,
	BIKE,
	PERSON
};

/** RecordFactory is the client */
class RecordFactory
{
    
private:
	unordered_map<RecordType, unique_ptr<Record>, hash<int> > m_records;

public:
	RecordFactory()
	{
    
		m_records[CAR]    = make_unique<CarRecord>("Ferrari", 5050);
		m_records[BIKE]   = make_unique<BikeRecord>("Yamaha", 2525);
		m_records[PERSON] = make_unique<PersonRecord>("Tom", 25);
	}

	unique_ptr<Record> createRecord(RecordType recordType)
	{
    
		return m_records[recordType]->clone();
	}
};

int main()
{
    
	RecordFactory recordFactory;

	auto record = recordFactory.createRecord(CAR);
	record->print();

	record = recordFactory.createRecord(BIKE);
	record->print();

	record = recordFactory.createRecord(PERSON);
	record->print();
}

Another example:

To implement the pattern, declare an abstract base class that specifies a pure virtual clone() member function. Any class that needs a "polymorphic constructor" capability derives itself from the abstract base class, and implements the clone() operation.

The client, instead of writing code that invokes the new operator on a hard-wired class name, calls the clone() member function on the prototype, calls a factory member function with a parameter designating the particular concrete derived class desired, or invokes the clone() member function through some mechanism provided by another design pattern.

 class CPrototypeMonster
 {
    
 protected:            
     CString           _name;
 public:
     CPrototypeMonster();
     CPrototypeMonster( const CPrototypeMonster& copy );
     virtual ~CPrototypeMonster();
 
     virtual CPrototypeMonster*    Clone() const=0; // This forces every derived class to provide an overload for this function.
     void        Name( CString name );
     CString    Name() const;
 };

 class CGreenMonster : public CPrototypeMonster
 {
    
 protected: 
     int         _numberOfArms;
     double      _slimeAvailable;
 public:
     CGreenMonster();
     CGreenMonster( const CGreenMonster& copy );
     ~CGreenMonster();
 
     virtual CPrototypeMonster*    Clone() const;
     void  NumberOfArms( int numberOfArms );
     void  SlimeAvailable( double slimeAvailable );
 
     int         NumberOfArms() const;
     double      SlimeAvailable() const;
 };

 class CPurpleMonster : public CPrototypeMonster
 {
    
 protected:
     int         _intensityOfBadBreath;
     double      _lengthOfWhiplikeAntenna;
 public:
     CPurpleMonster();
     CPurpleMonster( const CPurpleMonster& copy );
     ~CPurpleMonster();
 
     virtual CPrototypeMonster*    Clone() const;
 
     void  IntensityOfBadBreath( int intensityOfBadBreath );
     void  LengthOfWhiplikeAntenna( double lengthOfWhiplikeAntenna );
 
     int       IntensityOfBadBreath() const;
     double    LengthOfWhiplikeAntenna() const;
 };

 class CBellyMonster : public CPrototypeMonster
 {
    
 protected:
     double      _roomAvailableInBelly;
 public:
     CBellyMonster();
     CBellyMonster( const CBellyMonster& copy );
     ~CBellyMonster();
 
     virtual CPrototypeMonster*    Clone() const;
 
     void       RoomAvailableInBelly( double roomAvailableInBelly );
     double     RoomAvailableInBelly() const;
 };

 CPrototypeMonster* CGreenMonster::Clone() const
 {
    
     return new CGreenMonster(*this);
 }

 CPrototypeMonster* CPurpleMonster::Clone() const
 {
    
     return new CPurpleMonster(*this);
 }

 CPrototypeMonster* CBellyMonster::Clone() const
 {
    
     return new CBellyMonster(*this);
 }

A client of one of the concrete monster classes only needs a reference (pointer) to a CPrototypeMonster class object to be able to call the ‘Clone’ function and create copies of that object. The function below demonstrates this concept:

 void DoSomeStuffWithAMonster( const CPrototypeMonster* originalMonster )
 {
    
     CPrototypeMonster* newMonster = originalMonster->Clone();
     ASSERT( newMonster );
 
     newMonster->Name("MyOwnMonster");
     // Add code doing all sorts of cool stuff with the monster.
     delete newMonster;
 }

Now originalMonster can be passed as a pointer to CGreenMonster, CPurpleMonster or CBellyMonster.

Singleton[edit]

The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. It is named after the singleton set, which is defined to be a set containing one element. This is useful when exactly one object is needed to coordinate actions across the system.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值