23种设计模式 - C++实现

目录

设计模式的基本原则

1) 开放封闭原则 (OCP,Open For Extension, Closed For Modification Principle)

2) 单一职责原则 (SRP,Single Responsibility Principle)

3) 依赖倒置原则 (DIP,Dependence Inversion Principle)

4) 接口隔离原则 (ISP,Interface Segegation Principle)

5) 里氏替换原则 (LSP, Liskov Substitution Principle)

6) 优先使用组合而不是继承原则(CARP,Composite/Aggregate Reuse Principle)

7) 迪米特法则(LOD,Law of Demeter)

创建型模式

单例模式

Abstract

How

Template

简单工厂模式

Abstract

Demo

工厂模式

Abstract

Demo

抽象工厂

Abstract

Demo

建造者模式

Abstract

Role

Compare

Demo

原型模式prototype

Abstract

Demo

结构型模式

代理模式

Abstract

Role

Demo

装饰模式

Abstract

Demo

适配器模式

Abstract

Demo

组合模式

Abstract

Role

Demo

桥接模式 bridge

Abstract

Role

Demo

外观模式 facade

Abstract

Role

Demo

享元模式flyweight

Abstract

Role

Demo

行为型模式

模板模式

Abstract

Role

Demo

命令模式

abstract

Role

Demo

责任链模式

abstract

Role

Demo

策略模式

Abstract

Role

Demo

中介者模式

abstract

Role

Demo

观察者模式observer

abstract

Role

Demo

备忘录模式

abstract

Role

Demo

访问者模式

abstract

Role

Demo

状态模式

abstract

Role

Demo

解释器模式interpreter

abstract

Role

Demo

迭代器模式iterator

abstract

Role


设计模式的基本原则

1) 开放封闭原则 (OCP,Open For Extension, Closed For Modification Principle)

类的改动是通过增加代码进行的,而不是修改源代码。

2) 单一职责原则 (SRP,Single Responsibility Principle)

类的职责要单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。

3) 依赖倒置原则 (DIP,Dependence Inversion Principle)

依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程。

4) 接口隔离原则 (ISP,Interface Segegation Principle)

不应该强迫客户的程序依赖他们不需要的接口方法。一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中去。

5) 里氏替换原则 (LSP, Liskov Substitution Principle)

任何抽象类出现的地方都可以用他的实现类进行替换。实际就是虚拟机制,语言级别实现面向对象功能。

6) 优先使用组合而不是继承原则(CARP,Composite/Aggregate Reuse Principle)

如果使用继承,会导致父类的任何变换都可能影响到子类的行为。

如果使用对象组合,就降低了这种依赖关系。

7) 迪米特法则(LOD,Law of Demeter)

一个对象应当对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统的可维护性。例如在一个程序中,各个模块之间相互调用时,通常会提供一个统一的接口来实现。这样其他模块不需要了解另外一个模块的内部实现细节,这样当一个模块内部的实现发生改变时,不会影响其他模块的使用。

创建型模式

包括了6种设计模式: 单例模式、简单工厂、 工厂、抽象工厂、建造者模式、原型模式。

单例模式

Abstract

单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。

GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

How

  1. 构造函数私有化
  2. 提供一个全局的静态方法
  3. 在类中定义一个静态指针,指向本类的变量的静态变量指针
  4. 懒汉式单例getInstance 时new, 饿汉式静态函数申明时new
  5. 如果设计单例模板,必须使用懒汉式单例

Template

#include
#include 
#include 

using namespace std;
template 
class Singleton
{
public:
 
  template
  static T* GetInstance(Args&&... args)
  {
      std::call_once(flag, [&]() {
          m_pInstance=new T(std::forward(args)...);
      });
      return m_pInstance;
  }
  static void DestroyInstance()
  {
    delete m_pInstance;
    m_pInstance=nullptr;
  }
private:
  Singleton(void);
  virtual ~Singleton(void);
  Singleton(const Singleton&);
  Singleton& operator =(const Singleton&);
private:
  static T* m_pInstance;
  static std::once_flag flag;
};
template  T* Singleton::m_pInstance=nullptr;
template  std::once_flag Singleton::flag;
struct A
{
  A(){}
};
struct B
{
  B(int x){}
};
struct C
{
  C(int x,double y){}
};

void function() {
	A* a= Singleton::GetInstance();
	std::cout<<"address :" << a<join();
	th2->join();
	return 0;
}

简单工厂模式

Abstract

简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

角色

1.工厂(Creator)角色

简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

2.抽象(Product)角色

简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

3.具体产品(Concrete Product)角色

简单工厂模式所创建的具体实例对象

优缺点

在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。

Demo

include "iostream"
using namespace std;

//思想: 核心思想是用一个工厂,来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果。
//元素分析:
//抽象产品类:水果类
//具体的水果了:香蕉类、苹果类、梨子
//优点 适用于不同情况创建不同的类时
//缺点 客户端必须要知道基类和工厂类,耦合性差 增加一个产品,需要修改工厂类

class Fruit
{
public:
	virtual void getFruit() = 0;

protected:
private:
};


class Banana : public Fruit
{
public:
	virtual void getFruit()
	{
		cout<<"香蕉"<getFruit();
	
	Fruit *banana =  Factory::Create("banana");
	banana->getFruit();

	system("pause");

工厂模式

Abstract

工厂方法模式同样属于类的创建型模式又被称为多态工厂模式。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。

核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

角色

抽象工厂(Creator)角色

工厂方法模式的核心,任何工厂类都必须实现这个接口。

具体工厂(Concrete Creator)角色

具体工厂类是抽象工厂的一个实现,负责实例化产品对象。

抽象(Product)角色

工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品(Concrete Product)角色

工厂方法模式所创建的具体实例对象

Compare

工厂方法模式与简单工厂模式在结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。

工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。

当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。工厂方法模式退化后可以演变成简单工厂模式。

“开放-封闭”通过添加代码的方式,不是通过修改代码的方式完成功能的增强。

Demo

#include "iostream"
using namespace std;

class Fruit
{
public:
	virtual void sayname()
	{
		cout<<"fruit\n";
	}
};

class FruitFactory
{
public:
	virtual Fruit* getFruit()
	{
		return new Fruit();
	}
};


//香蕉
class Banana : public Fruit
{
public:
	virtual void sayname()
	{
		cout<<"Banana \n"<getFruit();
	fruit->sayname();

	delete fruit;
	delete ff;

	//2苹果
	ff = new AppleFactory();
	fruit = ff->getFruit();
	fruit->sayname();

	delete fruit;
	delete ff;

	cout<<"hello....\n";
	system("pause");
}

抽象工厂

Abstract

抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。

工厂模式只能生产一个产品。(要么香蕉、要么苹果)

抽象工厂可以一下生产一个产品族(里面有很多产品组成

Role

1. 抽象工厂(Creator)角色

抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。

2. 具体工厂(Concrete Creator)角色

具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。

3. 抽象(Product)角色

抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

4. 具体产品(Concrete Product)角色

抽象模式所创建的具体实例对象

23种设计模式 - C++实现_第1张图片

Demo

class Fruit
{
public:
	virtual void sayname()
	{
		cout<<"fruit\n";
	}
};

class FruitFactory
{
public:
	virtual Fruit* getApple()
	{
		return new Fruit();
	}
	virtual Fruit* getBanana()
	{
		return new Fruit();
	}
};

//南方香蕉
class SouthBanana : public Fruit
{
public:
	virtual void sayname()
	{
		cout<<"South Banana \n"<getApple();
	fruit->sayname();
	fruit = ff->getBanana();
	fruit->sayname();

	delete fruit;
	delete ff;

	ff = new NorthFruitFactory();
	fruit = ff->getApple();
	fruit->sayname();
	fruit = ff->getBanana();
	fruit->sayname();

	delete fruit;
	delete ff;

	cout<<"hello....\n";
	system("pause");
}

建造者模式

Abstract

Builder模式是为对象的创建而设计的模式- 创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象- 关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法。

Role

1) Builder:为创建产品各个部分,统一抽象接口。

2) ConcreteBuilder:具体的创建产品的各个部分,部分A, 部分B,部分C。

3) Director:构造一个使用Builder接口的对象。

4) Product:表示被构造的复杂对象。

ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

Compare

Factory模式中:

1、有一个抽象的工厂。

2、实现一个具体的工厂---汽车工厂。

3、工厂生产汽车A,得到汽车产品A。

4、工厂生产汽车B,得到汽车产品B。

这样做,实现了购买者和生产线的隔离。强调的是结果。

Builder模式:

1、引擎工厂生产引擎产品,得到汽车部件A。

2、轮胎工厂生产轮子产品,得到汽车部件B。

3、底盘工厂生产车身产品,得到汽车部件C。

4、将这些部件放到一起,形成刚好能够组装成一辆汽车的整体。

5、将这个整体送到汽车组装工厂,得到一个汽车产品。

这样做,目的是为了实现复杂对象生产线和其部件的解耦。强调的是过程

两者的区别在于:

Factory模式不考虑对象的组装过程,而直接生成一个我想要的对象。

Builder模式先一个个的创建对象的每一个部件,再统一组装成一个对象。

Factory模式所解决的问题是,工厂生产产品。

而Builder模式所解决的问题是工厂控制产品生成器组装各个部件的过程,然后从产品生成器中得到产品。

Demo

#include 
using namespace std;
#include "string"
class House
{
public:
	void setFloor(string floor)
	{
		this->m_floor = floor;
	}
	void setWall(string wall)
	{
		this->m_wall = wall;
	}
	void setDoor(string door)
	{
		this->m_door = door;
	}

	//
	string getFloor()
	{
		return m_floor;
	}
	string setWall()
	{
		return  m_wall;
	}
	string setDoor()
	{
		return m_door;
	}

protected:
private:
	string	m_floor;
	string	m_wall;
	string	m_door;
};

class Builder
{
public:
	virtual void makeFloor() = 0;
	virtual void makeWall() =  0;
	virtual void makeDoor() = 0;
	virtual House *GetHouse() = 0;
};

//公寓
class FlatBuild : public Builder
{
public:
	FlatBuild()
	{
		pHouse = new House;
	}
	virtual void makeFloor()
	{
		pHouse->setFloor("flat Door");
	}
	virtual void makeWall()
	{
		pHouse->setWall("flat Wall");
	}
	virtual void makeDoor()
	{
		pHouse->setDoor("flat Door");
	}
	virtual House *GetHouse()
	{
		return pHouse;
	}

private:
	House *pHouse;
};

//别墅
class VillaBuild : public Builder
{
public:
	VillaBuild()
	{
		pHouse = new House;
	}
	virtual void makeFloor()
	{
		pHouse->setFloor("villa floor");
	}
	virtual void makeWall()
	{
		pHouse->setWall("villa Wall");
	}
	virtual void makeDoor()
	{
		pHouse->setDoor("villa Door");
	}
	virtual House *GetHouse()
	{
		return pHouse;
	}
private:
	House *pHouse;
};

class Director
{
public:
	void Construct(Builder *builder)
	{
		builder->makeFloor();
		builder->makeWall();
		builder->makeDoor();
	}
protected:
private:
};


void main()
{
	//客户直接造房子
	House *pHose = new House;
	pHose->setDoor("wbm门");
	pHose->setFloor("wbmFloor");
	pHose->setWall("wbmWall");
	delete pHose;

	
	/* //工程队直接造房子 
	Builder *builder = new FlatBuild;
	builder->makeFloor();
	builder->makeWall();
	builder->makeDoor();
	*/

	//指挥者(设计师)指挥 工程队 和 建房子
	Director *director = new Director;

	//建公寓
	Builder *builder = new FlatBuild;
	director->Construct(builder); //设计师 指挥 工程队干活
	House *house = builder->GetHouse();
	cout << house->getFloor() << endl;
	delete house;
	delete builder;

	//建别墅
	builder = new VillaBuild;
	director->Construct(builder); //设计师 指挥 工程队干活
	house = builder->GetHouse();
	cout << house->getFloor() << endl;
	delete house;
	delete builder;
	
	delete director;
	
	system("pause");
	return ;
}

原型模式prototype

Abstract

Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。

1)由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。

2)目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。

3)根据对象克隆深度层次的不同,有浅度克隆与深度克隆。

23种设计模式 - C++实现_第2张图片

Demo

class Person
{
public:
	virtual Person *Clone() = 0;
	virtual void printT() = 0;

};

class JavaProgrammer : public Person
{
public:
	JavaProgrammer()
	{
		this->m_name = "";
		this->m_age = 0;
		m_resume = NULL;
	}
	JavaProgrammer(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
		m_resume = NULL;
	}

	~JavaProgrammer()
	{
		if (m_resume!= NULL)
		{
			free(m_resume);
			m_resume = NULL;
		}
	}
	virtual Person *Clone()
	{
		JavaProgrammer *p = new JavaProgrammer;
		*p = *this;
		return p;
	}

	void setResume(char *resume)
	{
		m_resume = new char[strlen(resume) + 1];
		strcpy(m_resume, resume);
	}

	virtual void printT()
	{
		cout << "m_name:" << m_name << "\t" << "m_age:" << m_age << endl;
		if (m_resume != NULL)
		{
			cout << m_resume << endl;
		}
	}
protected:
private:
	string	m_name;
	int		m_age;
	char	*m_resume;
};

void main()
{
	JavaProgrammer javaperson1("张三", 30);
	javaperson1.setResume("我是java程序员");
	Person *p2 = javaperson1.Clone();  //对象具有自我复制功能 注意深拷贝和浅拷贝问题
	p2->printT();

	delete p2;
	
	cout<<"hello..."< 
  

结构型模式

结构型模式主要包括代理模式、装饰模式、适配器模式、组合模式、桥接模式、外观模式、享元模式。

代理模式

Abstract

Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。

所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。

Role

subject(抽象主题角色):

真实主题与代理主题的共同接口。

RealSubject(真实主题角色):

定义了代理角色所代表的真实对象。

Proxy(代理主题角色):

含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真是主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。

适合于:

为其他对象提供一种代理以控制对这个对象的访问

Demo

#include 
#include 
using namespace std;
//定义接口
class Interface
{
    public:
    virtual void Request()=0;
};
//真实类
class RealClass : public Interface
{
public:
virtual void Request()
{
cout<<"真实的请求"<Request();
delete m_realClass;
}
};


int main()
{
    ProxyClass* test=new ProxyClass();
    test->Request();
    return 0;
}

装饰模式

Abstract

装饰(Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。

装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

但是在C++中语法层级不支持无感知装饰。

Demo

#include 
using namespace std;

class Car
{
    public:
    virtual void show() = 0;
    protected:
    private:
};

class RunCar : public Car
{
public:
void run()
{
cout << "可以跑" << endl;
}
virtual void show()
{
run();
}
protected:
private:
};

class SwimCarDirector : public Car
{
public:
SwimCarDirector(Car *p)
{
m_p = p;
}

void swim()
{
cout << "可以游" << endl;
}

virtual void show()
{
m_p->show();
swim();
}
private:
Car *m_p;
};

class FlyCarDirector : public Car
{
public:
FlyCarDirector(Car *p)
{
m_p = p;
}

void fly()
{
cout << "可以飞" << endl;
}
virtual void show()
{
m_p->show();
fly();
}
private:
Car *m_p;
};

void main()
{
    Car *runcar = NULL;
    runcar = new RunCar;
    runcar->show();
    
    cout <<"车开始装饰swim"<show();
    
    cout <<"车开始装饰fly"<show();
    
    delete flyCar;
    delete swimCar;
    delete runcar;
    
    return ;
}

适配器模式

Abstract

Adapter模式也叫适配器模式,是构造型模式之一,通过Adapter模式可以改变已有类(或外部类)的接口形式。

适用于:

是将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

Demo

#include 
using namespace std;

class Current18v
{
    public:
    void use18vCurrent()
    {
        cout << "使用18v的交流电" << endl;
    }
    protected:
    private:
};


class Current220v
{
    public:
    void use220vCurrent()
    {
        cout << "使用220v的交流电" << endl;
    }
    protected:
    private:
};


class Adapter : public Current18v
{
public:
Adapter(Current220v *p220v)
{
m_p220v = p220v;
}
void use18vCurrent()
{
cout << "adapter中使用电流" << endl;
m_p220v->use220vCurrent();
}
protected:
private:
Current220v *m_p220v;
};

void main()
{
    Current220v *p220v = new Current220v;
    Adapter *padapter = new Adapter(p220v);
    padapter->use18vCurrent();
    
    delete p220v;
    delete padapter;
    system("pause");
    return ;
}

组合模式

Abstract

Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。

Role

Component (树形结构的节点抽象)

- 为所有的对象定义统一的接口(公共属性,行为等的定义)

- 提供管理子节点对象的接口方法

- [可选]提供管理父节点对象的接口方法

Leaf (树形结构的叶节点)

Component的实现子类

Composite(树形结构的枝节点)

Component的实现子类

适用于:

单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分--整体”

Demo

#include 
using namespace std;
#include "list"
#include "string"

//
class IFile
{
public:
	virtual void display() = 0;
	virtual int add(IFile *ifile) = 0;
	virtual int remove(IFile *ifile) = 0;
	virtual list* getChild() = 0;
protected:
private:
};

class File : public IFile
{
public:
	File(string name)
	{
		m_list = NULL;
		m_name = "";
		m_name = name;
	}
	~File()
	{
		if (m_list != NULL)
		{
			delete m_list;
		}
	}
	virtual void display()
	{
		cout << m_name << endl;
	}
	virtual int add(IFile *ifile)
	{
		return -1;
	}
	virtual int remove(IFile *ifile)
	{
		return -1;
	}
	virtual list* getChild() 
	{
		return NULL;
	}

private:
	list *	m_list;
	string		m_name;

};

class Folder : public IFile
{
public:
	Folder(string name)
	{
		m_name = name;
		m_list = new list;
	}
	~Folder()
	{
		if (m_list == NULL)
		{
			delete m_list;
		}
	}
	virtual void display()
	{
		cout << m_name << endl;
	}
	virtual int add(IFile *ifile)
	{
		m_list->push_back(ifile);
		return 0;
	}
	virtual int remove(IFile *ifile)
	{
		m_list->remove(ifile);
		return 0;
	}
	virtual list* getChild() 
	{
		return m_list;
	}

private:
	list *	m_list;
	string			m_name;

};

void showTree(IFile *ifile, int level)
{
	list *l = NULL;
	int i = 0;
	for (i=0; idisplay();

	l = ifile->getChild();
	if (l != NULL)
	{
		for (list::iterator it=l->begin(); it!=l->end(); it++)
		{
			if ( (*it)->getChild() == NULL)
			{
				for (i=0; i<=level; i++) //注意 <= 
				{
					printf("\t");
				}
				(*it)->display();
			}
			else
			{
				showTree((*it), level + 1);
			}

		}
	}
}

void main()
{
	Folder *root = new Folder("C:");

	Folder *dir1 = new Folder("111dir");
	File *txt1 = new File("aaa.txt");

	Folder *dir12 = new Folder("222dir");
	//dir12->display();
	File *txt12 = new File("222.txt");
	//txt12->display();

	
	root->display();
	root->add(dir1);
	root->add(txt1);

	dir1->add(dir12);
	dir1->add(txt12);

	/*
	list *l = dir1->getChild();
	for (list::iterator it=l->begin(); it!=l->end(); it++)
	{
		(*it)->display();
	}
	*/
	//开发一个递归函数 现在根结点下的所有子结点
	cout << "测试递归函数" << endl;

	showTree(root, 0);

	delete txt12;
	delete dir12;
	delete dir1;
	delete txt1;
	delete root;
	cout<<"hello..."< 
  

桥接模式 bridge

Abstract

Bridge 模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。

Role

23种设计模式 - C++实现_第3张图片

Client

Bridge模式的使用者

Abstraction

抽象类接口(接口或抽象类)维护对行为实现(Implementor)的引用

Refined Abstraction

Abstraction子类

Implementor

行为实现类接口(Abstraction接口定义了基于Implementor接口的更高层次的操作)

ConcreteImplementor

Implementor子类

Demo

class Engine
{
public:
	virtual void installEngine() = 0;
};

class Engine4000 : public Engine
{
public:
	virtual void installEngine()
	{
		cout << "安装发动机 Engine4000" << endl;
	}
};

class Engine3500 : public Engine
{
public:
	virtual void installEngine()
	{
		cout << "安装发动机 Engine 3500" << endl;
	}
};

class Car
{
public:
	Car(Engine *pengine)
	{
		m_engine = pengine;
	}
	virtual void installEngine() = 0;

protected:
	Engine *m_engine;
};

class BMW7 :public Car
{
public:
	BMW7(Engine *p) : Car(p)
	{

	}

	//注意车的安装  和 发动机的安装 不同之处
	virtual void installEngine()
	{
		cout << "BMW7 " ; 
		m_engine->installEngine();
	}
protected:
private:
};

void main163()
{
	Engine4000 *e4000 = new Engine4000;
	BMW7 *bmw7 = new BMW7(e4000);
	bmw7->installEngine();

	delete bmw7;
	delete e4000;
}
void main()
{
	//main1601();
	//main1602();
	main163();
	system("pause");
}

外观模式 facade

Abstract

Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade。

Role

23种设计模式 - C++实现_第4张图片

Façade

为调用方, 定义简单的调用接口。

Clients

调用者。通过Facade接口调用提供某功能的内部类群。

Packages

功能提供者。指提供功能的类群(模块或子系统)

Demo

#include 
using namespace std;

class SystemA
{
public:
	void doThing()
	{
		cout << "systemA do...." << endl;
	}
};

class SystemB
{
public:
	void doThing()
	{
		cout << "systemA do...." << endl;
	}
};

class SystemC
{
public:
	void doThing()
	{
		cout << "systemA do...." << endl;
	}
};

class Facade
{
public:
	Facade()
	{
		a = new SystemA;
		b = new SystemB;
		c = new SystemC;
	}
	~Facade()
	{
		delete a;
		delete b;
		delete c;
	}

	void doThing()
	{
		a->doThing();
		b->doThing();
		c->doThing();
	}

protected:
private:
	SystemA *a;
	SystemB *b;
	SystemC *c;
};


void main1414()
{
	/*
	SystemA *a = new SystemA;
	SystemB *b = new SystemB;
	SystemC *c = new SystemC;

	a->doThing();
	b->doThing();
	c->doThing();

	delete a;
	delete b;
	delete c;
	*/

	Facade *f = new Facade;
	f->doThing();
	delete f;
	cout<<"hello..."< 
  

享元模式flyweight

Abstract

FlyWeight 模式也叫做享元模式,通过与其他的类似对象共享数据来减少内存的使用。

Role

23种设计模式 - C++实现_第5张图片

抽象享元角色:

所有具体享元类的父类,规定一些需要实现的公共接口。

具体享元角色:

抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。

享元工厂角色:

负责创建和管理享元角色。

使用场景:

是以共享的方式,高效的支持大量的细粒度的对象。

Demo

#include 
using namespace std;
#include "string"
#include "map"

class Person
{
public:
	Person(string name, int age, int sex)
	{
		this->name = name;
		this->age = age;
		this->sex = sex;
	}
	string getName()
	{
		return name;
	}
	int getAge()
	{
		return age;
	}
	int getSex()
	{
		return sex;
	}
protected:
	string	name;
	int		age;
	int		sex; //1男 2女
};

class Teacher : public Person
{
public:
	Teacher(string id, string name, int age, int sex) : Person(name, age, sex)
	{
		this->id = id;
	}

	string getId()
	{
		return id;
	}
	void printT()
	{
		cout << "id:" <::iterator it = m_tpool.begin();
			tmp = it->second;
			m_tpool.erase(it);
			delete tmp;
		}
	}
	//通过Teacher的pool,来存放老师结点,在TeacherFactory中创建老师、销毁老师
	Teacher *getTeacher(string tid)
	{
		string	name;
		int		age;
		int		sex;
		
		Teacher *tmp = NULL;
		map::iterator it =  m_tpool.find(tid);
		if (it == m_tpool.end())
		{
			cout << "id为: " << tid << " 的老师不存在,系统为你创建该老师,请输入以下信息" <> name;
			cout << "请输入老师年龄:";
			cin >> age;
			cout << "请输入老师性别 1男 2女:";
			cin >> sex;
			tmp = new Teacher(tid, name, age, sex);
			m_tpool.insert(pair(tid, tmp));
		}
		else
		{
			tmp = (it->second);
		}
		return tmp;
	}

private:
	map m_tpool;
};


void main()
{
	/*
	Teacher *t1 = new Teacher("001", "小李", 30, 1);
	Teacher *t2 = new Teacher("002", "小张", 30, 1);
	Teacher *t3 = new Teacher("001", "小李", 30, 1);
	Teacher *t4 = new Teacher("004", "小吴", 30, 1);
	//
	cout << "t1 t3的 工号一样,但是也不是同一个人 " << endl;
	delete t1;
	delete t2;
	delete t3;
	delete t4;
	*/
	TeacherFactory *teacherFactory = new TeacherFactory;
	Teacher *t1 = teacherFactory->getTeacher("001");
	t1->printT();

	Teacher *t2 = teacherFactory->getTeacher("001");
	t2->printT();
    delete teacherFactory;
	system("pause");
	return ;
}

行为型模式

行为型模式主要包括:模板模式、命令模式、责任链模式、策略模式、中介模式、观察者模式、备忘录模式、访问者模式、状态模式、解释模式、迭代器模式。

模板模式

Abstract

Template Method模式也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。

Role

23种设计模式 - C++实现_第6张图片

AbstractClass:

抽象类的父类

ConcreteClass:

具体的实现子类

templateMethod():

模板方法

method1()与method2():

具体步骤方法

Demo

#include 
using namespace std;

class MakeCar
{
public:
	virtual void makeHead() = 0;
	virtual void makeBody() = 0;
	virtual void makeTail() = 0;

public:   //把一组行为 变成 一个模板
	void make()
	{
		makeHead();
		makeBody();
		makeTail();
	}
	
protected:
private:
};

class MakeBus : public MakeCar
{
public:
	virtual void makeHead()
	{
		cout << "bus 组装 车头" << endl;
	}
	virtual void makeBody()
	{
		cout << "bus 组装 车身" << endl;
	}
	virtual void makeTail()
	{
		cout << "bus 组装 车尾" << endl;
	}
protected:
private:
};

class MakeJeep : public MakeCar
{
public:
	virtual void makeHead()
	{
		cout << "Jeep 组装 车头" << endl;
	}
	virtual void makeBody()
	{
		cout << "Jeep 组装 车身" << endl;
	}
	virtual void makeTail()
	{
		cout << "Jeep 组装 车尾" << endl;
	}
protected:
private:
};

void main()
{
	MakeCar *bus = new MakeBus;
	
	//bus->makeHead();
	//bus->makeBody();
	//bus->makeTail();
	bus->make();

	MakeCar *jeep = new MakeJeep;
	//jeep->makeHead();
	//jeep->makeBody();
	//jeep->makeTail();
	jeep->make();

	delete bus;
	delete jeep;

	cout<<"hello..."< 
  

命令模式

abstract

Command模式也叫命令模式,是行为设计模式的一种。Command模式通过被称为

Command的类封装了对目标对象的调用行为以及调用参数。

在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。

但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。

整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。-

调用前后需要对调用参数进行某些处理。调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。

Role

23种设计模式 - C++实现_第7张图片

Command

Command命令的抽象类。

ConcreteCommand

Command的具体实现类。

Receiver

需要被调用的目标对象。

Invorker

通过Invorker执行Command对象。

适用于:

是将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

Demo


#include 
using namespace std;
#include "list"

class Vendor
{
public:
	void sailbanana()
	{
		cout << "卖香蕉" << endl;
	}
	void sailapple()
	{
		cout << "卖苹果" << endl;
	}
};

class Command
{
public:
	virtual void sail() = 0;
};

class BananaCommand : public Command
{
public:
	BananaCommand(Vendor *v)
	{
		m_v = v;
	}
	Vendor *getV(Vendor *v)
	{
		return m_v;
	}

	void setV(Vendor *v)
	{
		m_v = v;
	}
	virtual void sail()
	{
		m_v->sailbanana();
	}
protected:
private:
	Vendor *m_v;
};

class AppleCommand : public Command
{
public:
	AppleCommand(Vendor *v)
	{
		m_v = v;
	}
	Vendor *getV(Vendor *v)
	{
		return m_v;
	}

	void setV(Vendor *v)
	{
		m_v = v;
	}
	virtual void sail()
	{
		m_v->sailapple();
	}
protected:
private:
	Vendor *m_v;
};

class Waiter
{
public:
	Command *getCommand()
	{
		return m_command;
	}
	void setCommand(Command *c)
	{
		m_command = c;
	}
	void sail()
	{
		m_command->sail();
	}
protected:
private:
	Command *m_command;
};

class AdvWaiter
{
public:
	AdvWaiter()
	{
		m_list = new list;
		m_list->resize(0);
	}
	~AdvWaiter()
	{
		delete m_list;
	}
	void setCommands(Command *c)
	{
		m_list->push_back(c);
	}
	list * getCommands()
	{
		return m_list;
	}
	void sail()
	{
		for (list::iterator it=m_list->begin(); it!=m_list->end(); it++ )
		{
			(*it)->sail();
		}
	}
protected:
private:
	list *m_list;
};

//小商贩 直接 卖 水果
void main25_01()
{
	Vendor *v = new Vendor;
	v->sailapple();
	v->sailbanana();

	delete v;
	return ;
}

//小商贩 通过命令 卖 水果
void main25_02()
{
	Vendor *v = new Vendor;
	AppleCommand *ac = new AppleCommand(v);
	ac->sail();

	BananaCommand *bc = new BananaCommand(v);
	bc->sail();

	delete bc;
	delete ac;
	delete v;
}

//小商贩 通过waiter 卖 水果
void main25_03()
{
	Vendor *v = new Vendor;
	AppleCommand *ac = new AppleCommand(v);
	BananaCommand *bc = new BananaCommand(v);

	Waiter *w = new Waiter;
	w->setCommand(ac);
	w->sail();

	w->setCommand(bc);
	w->sail();

	delete w;
	delete bc;
	delete ac;
	delete v;
}

//小商贩 通过advwaiter 批量下单 卖水果
void main25_04()
{
	Vendor *v = new Vendor;
	AppleCommand *ac = new AppleCommand(v);
	BananaCommand *bc = new BananaCommand(v);

	AdvWaiter *w = new AdvWaiter;
	w->setCommands(ac);
	w->setCommands(bc);
	w->sail();

	delete w;
	delete bc;
	delete ac;
	delete v;
}

void main()
{
	//main25_01();
	//main25_02();
	//main25_03();
	main25_04();
	system("pause");
}

责任链模式

abstract

Chain of Responsibility(CoR)模式也叫职责链模式或者职责连锁模式,是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。

例1:比如客户Client要完成一个任务,这个任务包括a,b,c,d四个部分。

首先客户Client把任务交给A,A完成a部分之后,把任务交给B,B完成b部分,...,直到D完成d部分。

例2:比如政府部分的某项工作,县政府先完成自己能处理的部分,不能处理的部分交给省政府,省政府再完成自己职责范围内的部分,不能处理的部分交给中央政府,中央政府最后完成该项工作。

例3:软件窗口的消息传播。

例4:SERVLET容器的过滤器(Filter)框架实现。

Role

23种设计模式 - C++实现_第8张图片

Handler

处理类的抽象父类。

concreteHandler

具体的处理类。

Demo

#include 
using namespace std;
class CarHandle
{
public:
	virtual void HandleCar() = 0;
	
public:
	CarHandle *setNextHandle(CarHandle *carhandle)
	{
		this->carhandle = carhandle;
		return this->carhandle;
	}
protected:
	CarHandle *carhandle;
};

class CarHandleHead : public CarHandle
{
public:
	virtual void HandleCar()
	{
		cout << "处理车头" << endl;
		if (this->carhandle != NULL)
		{
			carhandle->HandleCar();
		}
	}
};

class CarHandleBody : public CarHandle
{
public:
	virtual void HandleCar()
	{
		cout << "处理车身" << endl;
		if (this->carhandle != NULL)
		{
			carhandle->HandleCar();
		}
	}
};

class CarHandleTail : public CarHandle
{
public:
	virtual void HandleCar()
	{
		cout << "处理车尾" << endl;
		if (this->carhandle != NULL)
		{
			carhandle->HandleCar();
		}
	}
};

void main()
{
	CarHandleHead *head = new CarHandleHead;
	CarHandleBody *body = new CarHandleBody;
	CarHandleTail *tail = new CarHandleTail;

	head->setNextHandle(body);
	body->setNextHandle(tail);
	tail->setNextHandle(NULL);

	//处理
	head->HandleCar();
	delete head;
	delete body;
	delete tail;
	system("pause");
	return ;
}

策略模式

Abstract

Strategy模式也叫策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略)。Strategy模式主要用来平滑地处理算法的切换。

Role

23种设计模式 - C++实现_第9张图片

trategy:

策略(算法)抽象。

ConcreteStrategy
各种策略(算法)的具体实现。

Context
策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。策略由外部环境决定。

Demo

//Symmetric encryption
class Strategy
{
public:
	virtual void SymEncrypt() = 0;
};

class Des : public Strategy
{
public:
	virtual void SymEncrypt()
	{
		cout << "Des 加密" << endl; 
	}
};

class AES : public Strategy
{
public:
	virtual void SymEncrypt()
	{
		cout << "AES 加密" << endl; 
	}
};


class Context
{
public:
	Context(Strategy *strategy)
	{
		p = strategy;
	}
	void Operator()
	{
		p->SymEncrypt();
	}
private:
	Strategy *p;
};


//算法的实现 和 客户端的使用 解耦合
//使得算法变化,不会影响客户端
void main()
{
	/* 不符合开闭原则
 	Strategy *strategy = NULL;
	strategy = new AES;
	strategy->SymEncrypt();
	delete strategy;

	strategy = new Des;
	strategy->SymEncrypt();
	delete strategy;
	*/
	Strategy *strategy = NULL;
	Context *ctx = NULL;

	strategy = new AES;
	ctx = new Context(strategy);
	ctx->Operator();
	delete strategy;
	delete ctx;

	cout<<"hello..."< 
  

中介者模式

abstract

Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用。

中介就像是我们日常生活中的中介一样,中介掌握着最多的关系连接和资源,负责调配连接,这样可以减少非常多无效的连接。

Role

23种设计模式 - C++实现_第10张图片

Mediator抽象中介者

中介者类的抽象父类。

concreteMediator

具体的中介者类。

Colleague

关联类的抽象父类。

concreteColleague

具体的关联类。

适用于:

用一个中介对象,封装一些列对象(同事)的交换,中介者是各个对象不需要显示的相互作用,从而实现了耦合松散,而且可以独立的改变他们之间的交换。

Demo

#include 
using namespace std;
#include "string"

class Person
{
public:
	Person(string name, int sex, int condit)
	{
		m_name = name;
		m_sex = sex;
		m_condition = condit;
	}
	string getName()
	{
		return m_name;
	}
	int getSex()
	{
		return m_sex;
	}
	int getCondit()
	{
		return m_condition;
	}
	virtual void getParter(Person *p) = 0;

protected:
	string	m_name;	//
	int		m_sex; //1男  2女
	int		m_condition; //123456789;
};

class Man : public Person
{
public: 
	Man(string name, int sex, int condit):Person(name, sex, condit)
	{
		;
	}
	virtual void getParter(Person *p)
	{
		if (this->getSex() == p->getSex())
		{
			cout << "No No No 我不是同性恋" << endl;
		}
		if (this->getCondit() == p->getCondit())
		{
			cout << this->getName() << " 和 " << p->getName() << "绝配" << endl;
		}
		else
		{
			cout << this->getName() << " 和 " << p->getName() << "不配" << endl;
		}
	}
protected:

};

class Woman : public Person
{
public: 
	Woman(string name, int sex, int condit):Person(name, sex, condit)
	{
		;
	}
	virtual void getParter(Person *p)
	{
		if (this->getSex() == p->getSex())
		{
			cout << "No No No 我不是同性恋" << endl;
		}
		if (this->getCondit() == p->getCondit())
		{
			cout << this->getName() << " 和 " << p->getName() << "绝配" << endl;
		}
		else
		{
			cout << this->getName() << " 和 " << p->getName() << "不配" << endl;
		}
	}
protected:

};

//以上  Woman  Man类的太紧密 需要解耦合
void main1901()
{
	
	Woman *w1 = new Woman("小芳", 2, 4);
	Man *m1 = new Man("张三", 1, 3);
	Man *m2 = new Man("李四", 1, 4);

	w1->getParter(m1);
	w1->getParter(m2);

	delete w1;
	delete m1;
	delete m2;
	
	return ;
}

class Mediator ;
class Person2
{
public:
	Person2(string name, int sex, int condition, Mediator *m)
	{
		m_name = name;
		m_sex = sex;
		m_condition = condition;
		m_m = m;
	}
	string getName()
	{
		return m_name;
	}
	int getSex()
	{
		return m_sex;
	}
	int getCondit()
	{
		return m_condition;
	}
	
	Mediator *getMediator()
	{
		return m_m;
	}
public:
	virtual void getParter(Person2 *p) = 0;

protected:
	string	m_name;	//
	int		m_sex; //1男  2女
	int		m_condition; //123456789;
	Mediator *m_m;
};


class Mediator 
{
public:
	Mediator()
	{
		pMan = NULL;
		pWoman = NULL;
	}
	void setWoman(Person2 *p)
	{
		pWoman = p;
	}
	void setMan(Person2 *p)
	{
		pMan = p;
	}

	void getPartner()
	{
		if (pMan->getSex() == pWoman->getSex())
		{
			cout << "No No No 我不是同性恋" << endl;
		}
		if (pMan->getCondit() == pWoman->getCondit())
		{
			cout << pMan->getName() << " 和 " << pWoman->getName() << "绝配" << endl;
		}
		else
		{
			cout << pMan->getName() << " 和 " << pWoman->getName() << "不配" << endl;
		}
	}

protected:
private:
	Person2	*pMan;
	Person2	*pWoman;
};

class Woman2 : public Person2
{
public:
	Woman2(string name, int sex, int condition, Mediator *m) : Person2(name, sex, condition, m)
	{
		;
	}
	virtual void getParter(Person2 *p)
	{
		this->getMediator()->setWoman(this);
		this->getMediator()->setMan(p);
		this->getMediator()->getPartner();
	}
private:
};

class Man2 : public Person2
{
public:
	Man2(string name, int sex, int condition, Mediator *m) : Person2(name, sex, condition, m)
	{
		;
	}
	virtual void getParter(Person2 *p)
	{
		this->getMediator()->setMan(this);
		this->getMediator()->setWoman(p);
		this->getMediator()->getPartner();
	}
private:
};

void main1902()
{
	Mediator *mediator = new Mediator;
	Woman2 *w1 = new Woman2("小芳", 2, 4, mediator);
	Man2 *m1 = new Man2("张三", 1, 3, mediator);
	Man2 *m2 = new Man2("李四", 1, 4, mediator);

	w1->getParter(m1);
	w1->getParter(m2);

	delete w1;
	delete m1;
	delete m2;
	delete mediator;
}
void main()
{
	//main1901(); //问题的引出
	main1902(); //用中介者模式 进行优化
	system("pause");
}

观察者模式observer

abstract

Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

Role

23种设计模式 - C++实现_第11张图片

23种设计模式 - C++实现_第12张图片

Subject(被观察者)
被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。

ConcreteSubject
被观察者的具体实现。包含一些基本的属性状态及其他操作。

Observer(观察者)
接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。

ConcreteObserver
观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

Demo

#include 
using namespace std;
#include "vector"
#include "string"

class Secretary;

//玩游戏的同事类(观察者)
class PlayserObserver
{
public:
	PlayserObserver(string name, Secretary *secretary)
	{
		m_name = name;
		m_secretary = secretary;
	}
	void update(string action)
	{
		cout << "观察者收到action:" << action << endl;
	}
private:
	string		m_name;
	Secretary	*m_secretary;
};

//秘书类(主题对象,通知者)
class Secretary
{
public:
	void addObserver(PlayserObserver *o)
	{
		v.push_back(o);
	}
	void Notify(string action)
	{
		for (vector::iterator it= v.begin(); it!=v.end(); it++ )
		{
			(*it)->update(action);
		}
	}
	void setAction(string action)
	{
		m_action = action;
		Notify(m_action);
	}
private:
	string m_action;
	vector v;
};

void main()
{
	//subject 被观察者
	Secretary *s1 = new Secretary;

	//具体的观察者 被通知对象
	PlayserObserver *po1 = new PlayserObserver("小张", s1);
	//PlayserObserver *po2 = new PlayserObserver("小李", s1);
	s1->addObserver(po1);
	//s1->addObserver(po2);
	s1->setAction("老板来了");
	s1->setAction("老板走了");
	cout<<"hello..."< 
  

备忘录模式

abstract

Memento模式也叫备忘录模式,是行为模式之一,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。

Role

23种设计模式 - C++实现_第13张图片

Originator(原生者)

需要被保存状态以便恢复的那个对象。

Memento(备忘录)

该对象由Originator创建,主要用来保存Originator的内部状态。

Caretaker(管理者)

负责在适当的时间保存/恢复Originator对象的状态。

适用于:

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以将以后的对象状态恢复到先前保存的状态。

适用于功能比较复杂的,但需要记录或维护属性历史的类;或者需要保存的属性只是众多属性中的一小部分时Originator可以根据保存的Memo还原到前一状态。

Demo

#include 
using namespace std;
#include "string"

class MememTo
{
public:
	MememTo(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void setName(string name)
	{
		this->m_name = name;
	}
	string getName()
	{
		return m_name;
	}
	void setAge(int  age)
	{
		this->m_age = age;
	}
	int getAge()
	{
		return m_age;
	}
protected:
private:
	string	m_name;
	int		m_age;
};

class Person
{
public:
	Person(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void setName(string name)
	{
		this->m_name = name;
	}
	string getName()
	{
		return m_name;
	}
	void setAge(int  age)
	{
		this->m_age = age;
	}
	int getAge()
	{
		return m_age;
	}
	void printT()
	{
		cout << "name: " << m_name << "age: " << m_age << endl;
	}

public:

	//创建备份
	MememTo *createMememTo()
	{
		return new MememTo(m_name, m_age);
	}

	//恢复备份
	void SetMememTo(MememTo *memto)
	{
		m_name = memto->getName();
		m_age = memto->getAge();
	}

protected:
private:
	string	m_name;
	int		m_age;

};

//管理者
class Caretaker
{
public:
	Caretaker(MememTo *mem)
	{
		this->m_memto = mem;
	}
	MememTo *getMememTo()
	{
		return m_memto;
	}
	void setMememTo(MememTo *mem)
	{
		this->m_memto = mem;
	}
protected:
private:
	MememTo *m_memto;
};

void main23_01()
{
	Person *p = new Person("张三", 18);
	p->printT();

	//创建备份
	Caretaker *ct = new Caretaker(p->createMememTo());
	
	p->setAge(28);
	p->printT();

	//恢复信息
	p->SetMememTo(ct->getMememTo());
	p->printT();

	delete p;
	delete ct->getMememTo();

	return ;
}

void main23_02()
{
	Person *p = new Person("张三", 18);
	p->printT();

	//创建备份
	MememTo * membak = p->createMememTo();
	p->setAge(28);
	p->printT();

	//恢复信息
	p->SetMememTo(membak);
	p->printT();

	delete p;
	delete membak;
}

访问者模式

abstract

Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作角色和职责。

侧重于访问者的角色,适用于数据结构简单的情况。

Role

23种设计模式 - C++实现_第14张图片

抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。

具体访问者(ConcreteVisitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。

抽象节点(Element)角色:声明一个接受操作,接受一个访问者对象作为一个参量。

具体节点(ConcreteElement)角色:实现了抽象元素所规定的接受操作。

结构对象(ObiectStructure)角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如列(List)或集合(Set)。

适用于:

把数据结构作用于数据结构上的操作进行解耦合;

适用于数据结构比较稳定的场合

访问者模式总结:

访问者模式优点是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。

那访问者模式的缺点是是增加新的数据结构变得困难了

Demo

/*
案例需求:
比如有一个公园,有一到多个不同的组成部分;
该公园存在多个访问者:清洁工A负责打扫公园的A部分,清洁工B负责打扫公园的B部分,
公园的管理者负责检点各项事务是否完成,上级领导可以视察公园等等。
也就是说,对于同一个公园,不同的访问者有不同的行为操作,
而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性)。
*/
#include 
using namespace std;
#include "list"
#include "string"

class  ParkElement;
 
//不同的访问者 访问公园完成不同的动作 
class Visitor
{
public:
	virtual void visit(ParkElement *park) = 0;
};

class ParkElement //每一个
{
public:
	virtual void accept(Visitor *v) = 0;
};

class ParkA : public ParkElement
{
public:
	virtual void accept(Visitor *v)
	{
		v->visit(this);
	}
};

class ParkB : public ParkElement
{
public:
	virtual void accept(Visitor *v)
	{
		v->visit(this);
	}
};

class Park  : public ParkElement
{
public:
	Park()
	{
		m_list.clear();
	}
	void setPart(ParkElement *e)
	{
		m_list.push_back(e);
	}
public:
	void accept(Visitor *v)
	{
		for ( list::iterator it=m_list.begin(); it != m_list.end(); it++)
		{
			(*it)->accept(v);
		}
	}

private:
	list m_list;
};

class VisitorA : public Visitor
{
public:
	virtual void visit(ParkElement *park)
	{
		cout << "清洁工A访问公园A部分,打扫卫生完毕" << endl;
	}
};

class VisitorB : public Visitor
{
public:
	virtual void visit(ParkElement *park)
	{
		cout << "清洁工B 访问 公园B 部分,打扫卫生完毕" << endl;	
	}
};
class VisitorManager : public Visitor
{
public:
	virtual void visit(ParkElement *park)
	{
		cout << "管理员 检查整个公园卫生打扫情况" << endl;
	}
};

void main()
{
	VisitorA *visitorA = new VisitorA;
	VisitorB *visitorB = new VisitorB;
	
	ParkA *partA = new ParkA;
	ParkB *partB = new ParkB;

	//公园接受访问者a访问
	partA->accept(visitorA);
	partB->accept(visitorB);

	VisitorManager *visitorManager = new VisitorManager;
	Park * park = new Park;
	park->setPart(partA);
	park->setPart(partB);
	park->accept(visitorManager);

	cout<<"hello..."<
using namespace std;
#include "string"
#include "list"

//客户去银行办理业务
//m个客户
//n个柜员 

//将要 对象和要处理的操作分开,不同的柜员可以办理不同来访者的业务

class Element;

//访问者访问柜员 
class Visitor
{
public:
	virtual void visit(Element *element) = 0;
};


//柜员接受客户访问
class Element
{
public:
	virtual void accept(Visitor *v) = 0;
	virtual string getName() = 0;
};

//柜员A 员工
class EmployeeA : public Element
{
public:
	EmployeeA(string name)
	{
		m_name = name;
	}
	virtual void accept(Visitor *v)
	{
		v->visit(this); 
	}
	virtual string getName()
	{
		return m_name;
	}
private:
	string m_name;
};

//柜员B 员工
class EmployeeB : public Element
{
public:
	EmployeeB(string name)
	{
		m_name = name;
	}
	virtual void accept(Visitor *v)
	{
		v->visit(this);
	}
	string getName()
	{
		return m_name;
	}
private:
	string m_name;
};

class VisitorA : public Visitor
{
public:
	virtual void visit(Element *element)
	{
		cout << "通过" << element->getName() << "做A业务" << endl;
	}
};

class VisitorB : public Visitor
{
public:
	virtual void visit(Element *element)
	{
		cout << "通过" << element->getName() << "做B业务" << endl;
	}
};

void main26_01()
{
	EmployeeA *eA = new EmployeeA("柜员A");

	VisitorA *vA = new VisitorA;
	VisitorB *vB = new VisitorB;

	eA->accept(vA);
	eA->accept(vB);

	delete eA;
	delete vA;
	delete vB;
	return ;
}

//柜员B 员工
class Employees : public Element
{
public:
	Employees()
	{
		m_list = new list;
	}
	virtual void accept(Visitor *v)
	{
		for (list::iterator it = m_list->begin(); it != m_list->end(); it++  )
		{
			(*it)->accept(v);
		}
	}
	string getName()
	{
		return m_name;
	}
public:
	void addElement(Element *e)
	{
		m_list->push_back(e);
	}
	void removeElement(Element *e)
	{
		m_list->remove(e);
	}
private:
	list *m_list;
	string m_name;

};

void main26_02()
{
	EmployeeA *eA = new EmployeeA("柜员A");
	EmployeeA *eB= new EmployeeA("柜员B");

	Employees *es = new Employees;
	es->addElement(eA);
	es->addElement(eB);
	VisitorA *vA = new VisitorA;
	VisitorB *vB = new VisitorB;

	es->accept(vA);
	cout << "-------------" << endl;
	es->accept(vB);

	delete eA;
	delete eB 
		;
	delete vA;
	delete vB;

	return ;
}

void main()
{
	//main26_01();
	main26_02();
	system("pause");
}

状态模式

abstract

State模式也叫状态模式,是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。

适用于有限状态自动机FSM

Role

23种设计模式 - C++实现_第15张图片

23种设计模式 - C++实现_第16张图片

Context:用户对象

拥有一个State类型的成员,以标识对象的当前状态;

State:接口或基类

封装与Context的特定状态相关的行为;

ConcreteState:接口实现类或子类

实现了一个与Context某个状态相关的行为。

适用于:

对象的行为,依赖于它所处的当前状态。行为随状态改变而改变的场景。

适用于:通过用户的状态来改变对象的行为。

Demo

#include 
using namespace std;

class Worker;

class State
{
public:
	virtual void doSomeThing(Worker *w) = 0;
};

class Worker
{
public:
	Worker();
	int getHour()
	{
		return m_hour;
	}
	void setHour(int hour)
	{
		m_hour = hour;
	}
	State* getCurrentState()
	{
		return m_currstate;
	}
	void setCurrentState(State* state)
	{
		m_currstate = state;
	}

	void doSomeThing() //
	{
		m_currstate->doSomeThing(this);
	}
private:
	int		m_hour;
	State	*m_currstate; //对象的当前状态
};

class State1 : public State
{
public:
	 void doSomeThing(Worker *w);
};

class State2  : public State
{
public:
	 void doSomeThing(Worker *w);
};

void State1::doSomeThing(Worker *w)
{
	if (w->getHour() == 7 || w->getHour()==8)
	{
		cout << "吃早饭" << endl; 
	}
	else
	{ 
		delete w->getCurrentState();  //状态1 不满足 要转到状态2
		w->setCurrentState(new State2 );
		w->getCurrentState()->doSomeThing(w); //
	}
}


void State2::doSomeThing(Worker *w)
{
	if (w->getHour() == 9 || w->getHour()==10)
	{
		cout << "工作" << endl; 
	}
	else 
	{
		delete w->getCurrentState(); //状态2 不满足 要转到状态3 后者恢复到初始化状态
		w->setCurrentState(new State1); //恢复到当初状态
		cout << "当前时间点:" << w->getHour() << "未知状态" << endl;
	}
}

Worker::Worker()
{
	m_currstate = new State1;
}

void main()
{
	Worker *w1 = new Worker;
	w1->setHour(7);
	w1->doSomeThing();

	w1->setHour(9);
	w1->doSomeThing();

	delete w1;
	cout<<"hello..."< 
  

解释器模式interpreter

abstract

23种设计模式 - C++实现_第17张图片

Role

23种设计模式 - C++实现_第18张图片

Context

解释器上下文环境类。用来存储解释器的上下文环境,比如需要解释的文法等。

AbstractExpression

解释器抽象类。

ConcreteExpression

解释器具体实现类。

Demo

#include 
using namespace std;
#include "string"

class Context
{
public:
	Context(int num)
	{
		m_num = num;
	}
public:
	void setNum(int num)
	{
		m_num = num;
	}
	int getNum()
	{
		return m_num;
	}
	void setRes(int res)
	{
		m_res = res;
	}
	int getRes()
	{
		return m_res;
	}

private:
	int m_num;
	int m_res;

};

class Expression
{
public:
	virtual void interpreter(Context *context) = 0;
};

class PlusExpression : public Expression
{
public:
	virtual void interpreter(Context *context)
	{
		int num = context->getNum();
		num ++ ;
		context->setNum(num);
		context->setRes(num);
	}
};

class MinusExpression : public Expression
{
public:
	virtual void interpreter(Context *context)
	{
		int num = context->getNum();
		num -- ;
		context->setNum(num);
		context->setRes(num);
	}
};

void main()
{
	Context *pcxt = new Context(10);
	Expression *e1 = new PlusExpression;
	e1->interpreter(pcxt);
	cout << "PlusExpression:" << pcxt->getRes() << endl;

	Expression *e2 = new MinusExpression;
	e2->interpreter(pcxt);
	cout << "MinusExpression:" << pcxt->getRes() << endl;

	delete e2;
	delete e1;
	system("pause");
	return ;
}

迭代器模式iterator

abstract

Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。

意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

主要解决:不同的方式来遍历整个整合对象。

何时使用:遍历一个聚合对象。

如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。

Role

23种设计模式 - C++实现_第19张图片

23种设计模式 - C++实现_第20张图片

Iterator(迭代器接口):

该接口必须定义实现迭代功能的最小定义方法集

比如提供hasNext()和next()方法。

ConcreteIterator(迭代器实现类):

迭代器接口Iterator的实现类。可以根据具体情况加以实现。

Aggregate(容器接口):

定义基本功能以及提供类似Iterator iterator()的方法。

concreteAggregate(容器实现类):

容器接口的实现类。必须实现Iterator iterator()方法。

#include 
using namespace std;

typedef int Object ;
#define SIZE 5 

//注意类的顺序 
class MyIterator
{
public:
	virtual void First() = 0;
	virtual void Next() = 0;
	virtual bool IsDone() = 0;
	virtual Object CurrentItem() = 0;
};

class Aggregate
{
public:
	virtual Object getItem(int index) = 0;
	virtual MyIterator *CreateIterator() = 0;
	virtual int getSize() = 0;
};

class ContreteIterator : public MyIterator
{
public:
	ContreteIterator(Aggregate *ag) 
	{
		_ag = ag;
		_idx = 0;
	}
	~ContreteIterator()
	{
		_ag = NULL;
		_idx = 0;
	}

	virtual void First()
	{
		_idx = 0;
	}
	virtual void Next()
	{
		if (_idx <	_ag->getSize())
		{
			_idx ++;
		}
	}
	virtual bool IsDone()
	{
		return (_idx == _ag->getSize());
	}
	virtual Object CurrentItem()
	{
		return _ag->getItem(_idx);
	}

protected:
private:
	int			_idx;
	Aggregate	*_ag;
};

class ConcreteAggregate : public Aggregate
{
public:
	ConcreteAggregate()
	{
		for (int i=0; iCreateIterator();
	

	//通过迭代器 遍历 集合
	for (; !(it->IsDone()); it->Next() )
	{
		cout << it->CurrentItem() << " ";
	}
	
	//清理相关资源 
	delete it;
	delete ag;
}

void main()
{
	main21();
	system("pause");
	return ;
}

EngPerson
{
Public:
	Void dowork1(Car *car)
{
	Car. Run();
}
Void dowork2()
{
m_car.run()
}
Private:
	Car m_car;
}

你可能感兴趣的:(设计模式,设计模式,c++,单例模式)