大话设计模式(5)

原型模式

在这里插入图片描述
原型模式的优缺点:
优点:
复制自身。客户不知道需要对象的实际类型,只需知道它的抽象基类即可。(即有继承树的情况)
缺点:
必须先有一个对象实例(即原型)才能clone。

#include <iostream>
using namespace std;

class Monkey {
public:
	virtual ~Monkey(){}
	virtual Monkey* Clone() = 0;   //克隆
	virtual void Play() = 0;  //玩耍
};

class SunWuKong :public Monkey {
public:
	SunWuKong(string name) { m_strName = name; }
	~SunWuKong(){}

	//拷贝构造函数
	SunWuKong(const SunWuKong& other) {
		m_strName = other.m_strName;
	}
	//克隆
	Monkey* Clone() {
		//调用拷贝构造函数
		return new SunWuKong(*this);
	}
	void Play() {
		cout << m_strName << "play Golden-Hoop-Stick" << endl;
	}
private:
	string m_strName;
};

int main() {
	Monkey* swk = new SunWuKong("Qi Tian Da Sheng");

	Monkey* swk1 = swk->Clone();
	Monkey* swk2 = swk->Clone();

	swk1->Play();
	swk2->Play();

	if (swk2 != NULL) {
		delete swk2;
		swk2 = NULL;
	}
	if (swk1 != NULL) {
		delete swk1;
		swk1 = NULL;
	}
	if (swk != NULL) {
		delete swk;
		swk = NULL;
	}

	return 0;
}

模板方法模式

在这里插入图片描述
模板方法模式特点:

  • 模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势
  • 模板方法模式就是提供了一个很好的代码复用平台,它们在类库中尤为重要,它们提取了类库中的公共行为。
  • 当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠

模板方法模式的优缺点:
优点:

  • 封装了不变部分,扩展可变部分。把不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
  • 在父类中提取了公共的部分代码,便于代码复用。
  • 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
    缺点:
  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,提高了代码阅读的难度。

实例

#include <iostream>
using namespace std;

class DrinkTemplate {
public:
	//煮水
	virtual void BoildWater() {
		cout << "煮白开水" << endl;
	}
	//冲泡
	virtual void Brew() = 0;
	//倒入杯中
	virtual void PourInCup() = 0;
	//加入辅料
	virtual void AddSomething() = 0;

	//模板方法
	void MakeDrink() {
		BoildWater();
		Brew();
		PourInCup();
		AddSomething();
	}
};

//冲泡咖啡
class Coffee :public DrinkTemplate {
public:
	//煮水
	virtual void BoildWater() {
		cout << "煮矿泉水" << endl;
	}
	//冲泡
	virtual void Brew() {
		cout << "冲泡咖啡" << endl;
	}
	//倒入杯中
	virtual void PourInCup() {
		cout << "把咖啡倒入杯中" << endl;
	}
	//加入辅料
	virtual void AddSomething() {
		cout << "加入牛奶或糖" << endl;
	}
};

//冲泡茶
class Tea :public DrinkTemplate {
public:
	//冲泡
	virtual void Brew() {
		cout << "冲泡金银花" << endl;
	}
	//倒入杯中
	virtual void PourInCup() {
		cout << "把茶倒入杯中" << endl;
	}
	//加入辅料
	virtual void AddSomething() {
		cout << "加入枸杞" << endl;
	}
};

void test01() {
	Tea* tea = new Tea;
	tea->MakeDrink();

	cout << "---------------" << endl;
	Coffee* coffee = new Coffee;
	coffee->MakeDrink();
	delete coffee;
	delete tea;
}

int main() {
	test01();
	return 0;
}

外观模式

在这里插入图片描述
它完美体现了依赖倒转原则和迪米特法则的思想
在这个结构中包含两个角色,一个是外观类Facade,一个是子系统类。
Facade类(外观类):对外提供一个高层接口,将客户的请求交给适当子系统进行处理。
SubSystem Classes:是子系统的集合,每个子系统都完成一个特定的功能,这些子系统可以是某一模块,也可是某些类,Facade类将用户的请求交给这些子系统进行处理,需要注意的是子类中没有Facade类的任何信息,即没有对Facade类对象的引用。

#include <iostream>
using namespace std;

//子系统类
class SubSystemOne
{
public:
    void MethodOne()
    {
        cout << "call subsystem method one" << endl;
    }
};

class SubSystemTwo
{
public:
    void MethodTwo()
    {
        cout << "call subsystem method two" << endl;
    }
};

class SubSystemThree
{
public:
    void MethodThree()
    {
        cout << "call subsystem method three" << endl;
    }
};

class SubSystemFour
{
public:
    void MethodFour()
    {
        cout << "call subsystem method four" << endl;
    }
};


//外观类
class CFacade
{
public:
    void MethondA()
    {
        cout << "-----Call MethondA-----" << endl;
       
        systemOne.MethodOne();
    }

    void MethondB()
    {
        cout << "-----Call MethondB-----" << endl;

        systemOne.MethodOne();
        systemTwo.MethodTwo();
        systemThree.MethodThree();
    }

    void MethondC()
    {
        cout << "-----Call MethondC-----" << endl;

        systemThree.MethodThree();
        systemFour.MethodFour();
    }

    SubSystemOne systemOne;
    SubSystemTwo systemTwo;
    SubSystemThree systemThree;
    SubSystemFour systemFour;
};

int main() {
    CFacade Facede;
    Facede.MethondA();
    Facede.MethondB();
    Facede.MethondC();

    return 0;
}

外观模式使用场景:

  • 在设计初期阶段,应该要有意识的将不同的两个层分离,比如,数据访问层和业务逻辑层
  • 在开发阶段,子系统往往因为不断的重构演变而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少子系统小类的依赖
  • 在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但新的开发需要又依赖于它。可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade 对象交互,Facade与遗留代码交互所有复杂的工作。

建造者模式

建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
在这里插入图片描述

#include <iostream>
using namespace std;

//电脑产品
class Computer {
public:
	void SetCpu(string cpu) { m_strCpu = cpu; }
	void SetMainboard(string mainboard) { m_strMainboard = mainboard; }
	void SetRam(string ram) { m_strRam = ram; }
	void SetVideoCard(string videoCard) { m_strVideoCard = videoCard; }

	string GetCpu() { return m_strCpu; }
	string GetMainboard() { return m_strMainboard; }
	string GetRam() { return m_strRam; }
	string GetVideoCard() { return m_strVideoCard; }

private:
	string m_strCpu;
	string m_strMainboard;
	string m_strRam;
	string m_strVideoCard;
};

//建造者接口,组装流程
class IBuilder {
public:
	virtual void BuildCpu() = 0; //创建CPU 
	virtual void BuildMainboard() = 0; // 创建主板
	virtual void BuildRam() = 0;  //创建内存
	virtual void BuildVideoCard() = 0;  //创建显卡
	virtual Computer* GetResult() = 0;  //获取建造后的产品
};

//具体建造者
//ThinkPad 系列
class ThinkPadBuilder :public IBuilder {
public:
	ThinkPadBuilder() { m_pComputer = new Computer(); }
	void BuildCpu() { m_pComputer->SetCpu("i5-6200U"); }
	void BuildMainboard() { m_pComputer->SetMainboard("Intel DH57DD"); }
	void BuildRam() { m_pComputer->SetRam("DDR4"); }
	void BuildVideoCard() { m_pComputer->SetVideoCard("NVIDIA Geforce 920MX"); }
	Computer* GetResult() { return m_pComputer; }
	~ThinkPadBuilder() {
		if (m_pComputer != NULL) {
			delete m_pComputer;
			m_pComputer = NULL;
		}
	}
private:
	Computer* m_pComputer;
};
// Yoga系列
class YogaBuilder :public IBuilder {
public:
	YogaBuilder() { m_pComputer = new Computer(); }
	void BuildCpu() { m_pComputer->SetCpu("i7-7500U"); }
	void BuildMainboard() { m_pComputer->SetMainboard("Intel DP55KG"); }
	void BuildRam() { m_pComputer->SetRam("DDR5"); }
	void BuildVideoCard() { m_pComputer->SetVideoCard("NVIDIA Geforce 940MX"); }
	Computer* GetResult() { return m_pComputer; }
	~YogaBuilder(){
		if (m_pComputer != NULL) {
			delete m_pComputer;
			m_pComputer = NULL;
		}
	}
private:
	Computer* m_pComputer;
};

//构造指挥官
class Director {
public:
	void Create(IBuilder* builder) {
		builder->BuildCpu();
		builder->BuildMainboard();
		builder->BuildRam();
		builder->BuildVideoCard();
	}
};

int main() {
	Director* pDirector = new Director();
	ThinkPadBuilder* pTPBuilder = new ThinkPadBuilder();
	YogaBuilder* pYogaBuilder = new YogaBuilder();

	//组装ThinkPad、Yoga
	pDirector->Create(pTPBuilder);
	pDirector->Create(pYogaBuilder);

	//获取组装后的电脑
	Computer* pThinkPadComputer = pTPBuilder->GetResult();
	Computer* pYogaComputer = pYogaBuilder->GetResult();

	//测试输出
	cout << "-----ThinkPad-----" << endl;
	cout << "CPU: " << pThinkPadComputer->GetCpu() << endl;
	cout << "Mainboard: " << pThinkPadComputer->GetMainboard() << endl;
	cout << "Ram: " << pThinkPadComputer->GetRam() << endl;
	cout << "VideoCard: " << pThinkPadComputer->GetVideoCard() << endl;

	cout << "-----Yoga-----" << endl;
	cout << "CPU: " << pYogaComputer->GetCpu() << endl;
	cout << "Mainboard: " << pYogaComputer->GetMainboard() << endl;
	cout << "Ram: " << pYogaComputer->GetRam() << endl;
	cout << "VideoCard: " << pYogaComputer->GetVideoCard() << endl;

	return 0;
}

画小人实例

#include <iostream>
using namespace std;

class Builder
{
public:
	virtual void BuildHead() {}
	virtual void BuildBody() {}
	virtual void BuildLeftArm() {}
	virtual void BuildRightArm() {}
	virtual void BuildLeftLeg() {}
	virtual void BuildRightLeg() {}
};
//构造瘦人
class ThinBuilder : public Builder
{
public:
	void BuildHead() { cout << "build thin body" << endl; }
	void BuildBody() { cout << "build thin head" << endl; }
	void BuildLeftArm() { cout << "build thin leftarm" << endl; }
	void BuildRightArm() { cout << "build thin rightarm" << endl; }
	void BuildLeftLeg() { cout << "build thin leftleg" << endl; }
	void BuildRightLeg() { cout << "build thin rightleg" << endl; }
};
//构造胖人
class FatBuilder : public Builder
{
public:
	void BuildHead() { cout << "build fat body" << endl; }
	void BuildBody() { cout << "build fat head" << endl; }
	void BuildLeftArm() { cout << "build fat leftarm" << endl; }
	void BuildRightArm() { cout << "build fat rightarm" << endl; }
	void BuildLeftLeg() { cout << "build fat leftleg" << endl; }
	void BuildRightLeg() { cout << "build fat rightleg" << endl; }
};
//构造的指挥官
class Director
{
private:
	Builder* m_pBuilder;
public:
	Director(Builder* builder) { m_pBuilder = builder; }
	void Create() {
		m_pBuilder->BuildHead();
		m_pBuilder->BuildBody();
		m_pBuilder->BuildLeftArm();
		m_pBuilder->BuildRightArm();
		m_pBuilder->BuildLeftLeg();
		m_pBuilder->BuildRightLeg();
	}
};

int main()
{
	FatBuilder fat;
	Director director(&fat);
	director.Create();
	return 0;
}

观察者模式

在这里插入图片描述
观察者模式(Observer Pattern):定义了对象间的一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(被观察者)。当主题对象的状态发生更改时,会通知所有观察者,让它们能够自动更新。
观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

Subject: 目标
ConcreteSubject: 具体目标
Observer: 观察者
ConcreteObserver: 具体观察者
观察者模式很类似于C#中的事件,可是C++却没有事件机制,所以C++可以用观察者模式代替事件。

抽象主题(Subject)角色:抽象主题角色提供维护一个观察者对象聚集的操作方法,对聚集的增加、删除等。
具体主题(ConcreteSubject)角色:将有关状态存入具体的观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色负责实现抽象主题中聚集的管理方法。
抽象观察者(Observer)角色:为具体观察者提供一个更新接口。
具体观察者(ConcreteObserver)角色:存储与主题相关的自洽状态,实现抽象观察者提供的更新接口。

#include <iostream>
using namespace std;
#include <list>
#include <string>

//观察者抽象类
class Observer {
public:
	Observer(){}
	virtual ~Observer(){}
	virtual void Update(){}
};
//博客抽象类
class Blog {
public:
	Blog(){}
	virtual ~Blog(){}
	void Attach(Observer* observer) { m_observers.push_back(observer); }
	void Dettach(Observer* observer) { m_observers.remove(observer); }

	void Notify() {
		list<Observer*>::iterator it = m_observers.begin();
		for (; it != m_observers.end(); ++it) {
			(*it)->Update();
		}
	}
	virtual void setSatus(string s) { m_status = s; }
	virtual string getStatus() { return m_status; }
private:
	list<Observer*> m_observers;  //观察者链表
protected:
	string m_status;  //状态
};

//具体博客类
class Blog优快云 :public Blog {
private:
	string m_name;
public:
	Blog优快云(string name):m_name(name){}
	~Blog优快云(){}
	void setSatus(string s) { m_status = m_name + s; }  //设置具体状态信息
	string getStatus() { return m_status; }
};
//具体观察者类
class ObserverBlog :public Observer {
private:
	string m_name;
	Blog* m_blog;
public:
	ObserverBlog(string name, Blog* blog):m_name(name),m_blog(blog){}
	~ObserverBlog(){}
	void Update() {
		string status = m_blog->getStatus();
		cout << m_name << "-----------" << status << endl;
	}
};


int main() {
	Blog* blog = new Blog优快云("老板");
	Observer* observer1 = new ObserverBlog("小明", blog);
	Observer* observer2 = new ObserverBlog("夏美", blog);
	blog->Attach(observer1);
	blog->Attach(observer2);
	blog->setSatus("发表了新的博客");
	blog->Notify();
	delete observer2;
	delete observer1;
	delete blog;
	return 0;
}
#include <iostream>
using namespace std;
#include <list>
#include <string>

//抽象观察者类
class Observer {
public:
	virtual void Update() = 0;
};

//抽象主题类
class Subject {
public:
	virtual void Attach(Observer* observer) { m_observers.push_back(observer); }
	virtual void Detach(Observer* observer) { m_observers.remove(observer); }
	void Notify() {
		list<Observer*>::iterator it = m_observers.begin();
		for (; it != m_observers.end(); ++it) {
			(*it)->Update();
		}
	}
	virtual void setStatus(string s) = 0;
	virtual string getStatus() = 0;

private:
	list<Observer*> m_observers; //观察者链表
};

class Boss :public Subject {
public:
	void setStatus(string s) { m_status = s; }
	string getStatus() { return m_status; }
private:
	string m_status;
};


class Xiaoming :public Observer {
public:
	Xiaoming(Subject* subject) { this->subject = subject; }
	virtual void Update() {
		stopPlayGame();
	}
	void stopPlayGame() {
		string m_status = subject->getStatus();
		cout << m_status << "停止玩游戏" << endl;
	}
private:
	Subject* subject;
};

class Xiaoliu :public Observer {
public:
	Xiaoliu(Subject* subject) { this->subject = subject; }
	virtual void Update() {
		stopPlayPhone();
	}
	void stopPlayPhone() {
		cout << "老板回来了,停止玩手机" << endl;
	}
private:
	Subject* subject;
};

int main() {

	Boss* huhansan = new Boss();
	Observer* observer1 = new Xiaoming(huhansan);
	Observer* observer2 = new Xiaoliu(huhansan);

	huhansan->Attach(observer1);
	huhansan->Attach(observer2);
	huhansan->setStatus("胡汉三回来了,");
	huhansan->Notify();

	delete observer2;
	delete observer1;
	delete huhansan;

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值