设计模式总结(C++)

297 阅读4分钟

设计模式(Design pattern)

  • 在特定环境中解决某一问题方案
  • 被反复使用、多数人知晓的、经过分类的代码设计经验的总结
  • 重用代码, 让代码更容易被他人理解, 保证代码可靠性

设计模式基本原则

SOLID+D, 核心准则就是面向接口编程,定义接口层。

Single(单一职责)

类的职责要单一,对外只提供一种功能。

Open(开闭)

扩展开放,对修改关闭。类的改动是通过增加代码进行扩展的,而不是修改源代码

  • 使用接口/抽象类,定义系统的接口层,再通过增加具体实现类来进行扩展。

L(里氏替换)

父类出现的地方都可以用他的子类无缝替换

  • 在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

Interface(接口隔离)

一个接口应该只提供一种对外功能,不要把所有功能定义在一个接口。

D 迪米特法则 (最少知道原则)

  • 一个对象应当对其他对象尽可能少的了解,减少耦合
  • 各个模块之间相互调用时,通常会提供一个统一的接口来实现,来减少模块间的耦合

Depend(依赖倒置原则)

面向接口编程, 接口不能依赖具体实现, 实现可以依赖接口。

单例

适用于全局只有一个对象的场景

class singleton
{
protected:
    singleton(){}
private:
    static singleton* p;
public:
    static singleton* instance();
};
singleton* singleton::p = NULL;
singleton* singleton::instance()
{
    if (p == NULL)
        p = new singleton();
    return p;
}
  • 多线程问题

    1. C++对象创建分成分配内存+构造过程两步。
    2. 线程1分配好内存后,还没来得急构造和初始化成员变量,就进行线程切换了
    3. 线程2拿到所有权后,由于内存已经分配了, 就不会执行构造过程了, 这时候对象的属性值是未知的。
  • 解决办法

  1. 静态初始化(推荐)
    class singleton
    {
    private:
        static singleton* p;
    };
    singleton* singleton::p = new singleton;
    singleton* singleton::initance()
    {
        return p;
    }

因为静态属性在编译时就初始化到全局区了, 所以全局就只有一份了

  1. 创建对象过程中加锁

工厂模式

通过专门定义一个类负责创建其他类的实例,被创建的实例通常都具有共同的父类。

  • 简单工厂: 工厂类是具体实现, 添加新产品需要修改工厂类
  • 抽象工厂: 定义工厂接口, 这样添加新产品只要对应创建一个新的工厂实现类
FruitFactory * ff  = NULL; // 工厂接口
Fruit *fruit = NULL; // 产品

ff = new BananaFactory();
fruit = ff->getFruit();

// 添加新的工厂实现就可以定义新产品了
ff = new AppleFactory();
fruit = ff->getFruit();

原型模式prototype

  • 用来创建对象的拷贝对象。
  • 具有与原型一样的数据。
  • 浅拷贝

复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。

  • 深拷贝

会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象

适配器模式adapter

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


class Current18v
{
	void use18vCurrent()
	{
		cout << "使用18v的交流电" << endl;
	}
}
class Current220v
{
	void use220vCurrent()
	{
		cout << "使用220v的交流电" << endl;
	}
}
class Adapter : public Current18v
{
	Adapter(Current220v *p220v)
	{
		m_p220v = p220v;
	}
	void use18vCurrent()
	{
		cout << "adapter中使用电流" << endl;
		m_p220v->use220vCurrent(); // 适配方法中调用原始220V方法
	}
}
Current220v *p220v = new Current220v; // 220V
Adapter *padapter = new Adapter(p220v); //Adapter转换接口
padapter->use18vCurrent(); // 转换成18V

模板模式(template)

在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样可以把各个具体的子类和操作步骤接耦合

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

	void make() // 把一组行为变成一个模板
	{
		makeHead();
		makeBody();
		makeTail();
	}
};
class MakeBus : public MakeCar
{
	void makeHead()
	{
		cout << "bus 组装 车头" << endl;
	}
	void makeBody()
	{
		cout << "bus 组装 车身" << endl;
	}
	void makeTail()
	{
		cout << "bus 组装 车尾" << endl;
	}
}
class MakeJeep : public MakeCar
{
	void makeHead()
	{
		cout << "Jeep 组装 车头" << endl;
	}
	void makeBody()
	{
		cout << "Jeep 组装 车身" << endl;
	}
	void makeTail()
	{
		cout << "Jeep 组装 车尾" << endl;
	}
}
MakeCar *bus = new MakeBus;
bus->make();
MakeCar *jeep = new MakeJeep;
jeep->make();

责任链

链条式处理事情。工作流程化、消息处理流程化、事物流程化;

class CarHandle
{
	virtual void HandleCar() = 0;
	CarHandle *setNextHandle(CarHandle *carhandle)
	{
		this->carhandle = carhandle;
		return this->carhandle;
	}
};

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

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

class CarHandleTail : public CarHandle
{
	void HandleCar()
	{
		cout << "处理车尾" << endl;
		if (this->carhandle != NULL)
		{
			carhandle->HandleCar();
		}
	}
};
CarHandleHead *head = new CarHandleHead;
CarHandleBody *body = new CarHandleBody;
CarHandleTail *tail = new CarHandleTail;

head->setNextHandle(body);
body->setNextHandle(tail);
tail->setNextHandle(NULL);
//处理
head->HandleCar();

策略模式

准备一组算法,并将每一个算法封装起来,使得它们可以互换。

class Strategy
{
	virtual void SymEncrypt() = 0;
};
class Des : public Strategy
{
	virtual void SymEncrypt()
	{
		cout << "Des 加密" << endl; 
	}
};
class AES : public Strategy
{
	virtual void SymEncrypt()
	{
		cout << "AES 加密" << endl; 
	}
};
class Context
{
	Context(Strategy *strategy)
	{
		p = strategy;
	}
	void Operator()
	{
		p->SymEncrypt();
	}
private:
	Strategy *p;
};
Strategy *strategy = NULL;
Context *ctx = NULL;

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

代理模式(Delegate)

  • 定义接口,把一系列过程抽象出来, 用来指定代理双方可以做什么,必须做什么。

观察者模式

  • 当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。