C++实现|策略模式|工厂模式|单例模式|观察者模式|桥接模式

目录

关于工厂模式:

关于策略模式:

单例模式

观察者模式

桥接模式:


        C++实现|策略模式|工厂模式|单例模式|观察者模式|桥接模式

关于工厂模式:

        在工厂模式中,为了不对客户端暴露创建逻辑,我们通过一个共同的接口来创建对象。让其子类实现工厂接口,返回一个抽象的产品。

 如下使用工厂模式实现一个运算器的uml图: 

        使用工厂模式来实现计算器。

具体代码:

计算器类:

        此类为父类,统管所有运算符类的共同接口。

class Computer
{
public:
	Computer(){};

	Computer(int a,int b):numb1(a), numb2(b){};

	void setNumble(int a, int b)
	{
		numb1 = a;
		numb2 = b;
	}

	virtual double getResult() {};

	virtual ~Computer(){};
protected:
	double numb1, numb2;
};

 运算符类

        继承于计算器类,也是工厂要实例的对象。

class Plus :public Computer
{
	virtual double getResult()
	{
		return numb1 + numb2;
	}
};
class Minus :public Computer
{
	virtual double getResult()
	{
		return numb1 - numb2;
	}
};
class Mutiply :public Computer
{
	virtual double getResult()
	{
		return numb1* numb2;
	}
};
class Divide :public Computer
{
	virtual double getResult()
	{
		if (numb2 == 0)
			return 0;
		return numb1 /numb2;
	}
};

 工厂类

        根据需要对运算符类进行实例

class Factory
{
public:
	Computer* createOperate(char operate)
	{
		Computer* oper;

		switch (operate)
		{

		case '+':oper = new Plus(); break;

		case '-':oper = new Minus(); break;

		case '*':oper = new Mutiply(); break;

		case '/':oper = new Divide(); break;

		default:return nullptr;

		}
		return oper;
	}

	virtual ~Factory() {};
};

 客户端类

int main()
{
	int numb1, numb2;
	char operate;
	cout << "请输入第一个数字" << endl;
	cin >> numb1;
	cout << "选择运算符" << endl;
	cin >> operate;
	cout << "请输入第二个数字" << endl;
	cin >> numb2;

	Factory fac;
	Computer* func = fac.createOperate(operate);
	func->setNumble(numb1, numb2);
	double result=func->getResult();
	cout <<"结果为:" << result<<endl;;
	return 0;
}

关于策略模式:

         它定义了算法家族,分别封装起来,让它们之间可以相互转换,此模式让算法的变化不会影响到使用算法的客户。在策略模式中,我们创建表示各种策略的对象和一个为策略对象服务的 context 对象。

如下是工厂模式跟策略模式的结合:

        客户端无需看到策略的创建逻辑,只需要跟context对象打交道即可。而context对象则跟各个策略对象打交道,需要哪一个策略对象就创建哪一个。

        同时,策略抽象对象(指父类)仅是提供一个接口(一般为共同的行为)。子类则根据不同的需求来实现不同的行为。

UML图:

例子的UML图:

        结合工厂模式和策略模式来实现商场的打折、返利等功能。

 代码实现:

上下文类:

enum sale{normal=1,discount_8,rebate300_100 };
class StrategyContext
{
public:
	Strategy* con;


	void setStrategy(sale strategy)
	{
		switch (strategy)
		{
		case normal:con = new StrategyA(); break;
		case discount_8:con = new StrategyB(0.8); break;
		case rebate300_100:con = new StrategyC(300,100); break;
		default:return ;
		}
	};

	double acceptMoney(double result)
	{
		return con->acceptMoney(result);
	}
};

父类/算法总类:

class Strategy
{
public:

	virtual double acceptMoney(double result) { return result; }

};

子类/算法(a,b,c...)类:

class StrategyA:public Strategy
{
	double acceptMoney(double result)
	{
		return result;
	}
};
class StrategyB :public Strategy
{
public:
	StrategyB(){}
	StrategyB(double disc): m_discount(disc){};


	double acceptMoney(double result)
	{
		return result *m_discount;
	}
	double m_discount;
};
class StrategyC :public Strategy
{
public:
	StrategyC() {}

	StrategyC(double condition,double rebate) : m_condition(condition), m_rebate(rebate) {};

	double acceptMoney(double result)
	{
		double money = result;
		if (money >= m_condition)
		{
			double rebate = (int)(money / m_condition) * m_rebate;
			money = money - rebate;
		}	
		return money;
	}

	double m_condition;
	double m_rebate;
};

客户端:

int main() 
{
	int selected;
	double price;
	int count;
	cout << "1.正常销售 2.打八折 3.满300返100" << endl;
	cin >> selected;
	cout << "单价为:" << endl;
	cin >> price;
	cout << "数量为;" << endl;
	cin >> count;

	StrategyContext* con = new StrategyContext();
	con->setStrategy((sale)selected);
	cout << "价格为:" << con->acceptMoney(price * count) << endl;;
	return 0;
}

单例模式

        保证一个类有且仅有一个实例,并且可全局访问。

UML图:

 

饿汉单例模式

        提前初始化实例。

class Singleton
{
public:

	Singleton* getInstance()
	{
		return hunger;
	}

private:

	static Singleton* hunger;

};
Singleton* Singleton::hunger = new Singleton();

懒汉单例模式

        需要用到时再初始化实例,因为像是懒惰的行为,所以才叫懒汉。

class Singleton
{
public:

	Singleton* getInstance()
	{
		if (hunger == nullptr)
			hunger = new Singleton();
		return hunger;
	}

private:
	static Singleton* hunger;
};
Singleton* Singleton::hunger = nullptr;

观察者模式:

        定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

UML图:

 

例子的UML图:

观察者类:

#ifndef OBSERVER_H
#define  OBSERVER_H
#include<iostream>
using namespace std;
class Observer
{
public:
	Observer() {}
	Observer(string name) :m_name(name) {}

	virtual void update()
	{

	}

	string m_name;
};
class ObserverA :public Observer
{
public:
	ObserverA(string name)
	{
		m_name = name;
	}
	void update()
	{
		cout << "领导来了,快回座位!" << endl;
	}

};
class ObserverB :public Observer
{
public:
	ObserverB(string name)
	{
		m_name = name;
	}
	void update()
	{
		cout << "小姐姐来了,快看!" << endl;
	}
};
#endif

 主题类:

#ifndef SUBJECT_H
#define  SUBJECT_H
#include<list>
#include <algorithm>
#include"observer.h"
using namespace std;
class Subject
{
public:
	list<Observer*> observers;
	void attach(Observer* o)
	{
		observers.push_back(o);
	}

	void detach(Observer* o)
	{
		observers.remove(o);
	}
	void notify()
	{
		for (Observer* observer : observers) 
		{
			observer->update();
		}
	}

};
#endif

 客户端类:

#include<iostream>
#include"subject.h"
#include"observer.h"
using namespace std;
int main()
{
	Subject boss ;

	string delin = "delin";
	Observer* lin = new ObserverB(delin);

	boss.attach(lin);
	boss.notify();

	cout << "再增加一个人" << endl;
	string xioaBu = "xiaobu";
	Observer* Bu = new ObserverA(xioaBu);

	boss.attach(Bu);
	boss.notify();

	return 0 ;
}

 测试效果:

桥接模式:

        将抽象部分和实现部分分离,使他们都可以独立地灵活变化。

UML图:

 下面例子的UML图:

 品牌父类及子类:

#include"handsoft.h"
class Brand
{
public:
	Handsoft* soft;
	void setHandsoft(Handsoft* soft)
	{
		this->soft = soft;
	}
	virtual void run() {}

};

class BrandA:public Brand
{
public:

	virtual void run() 
	{
		cout << "手机品牌A开始启动!";
		soft->run();
	}
};

class BrandB :public Brand
{
public:

	virtual void run() 
	{
		cout << "手机品牌B开始启动!";
		soft->run();
	}
	
};

 软件父类及子类:

#include<iostream>
using namespace std;
class Handsoft
{
public:
	virtual void run(){}
};

class Game:public Handsoft
{
public:
	virtual void run() 
	{
		cout << "游戏软件启动!" << endl;
	}
};

class Comunication:public Handsoft
{
public:
	virtual void run() 
	{
		cout << "社交软件启动!" << endl;
	}
};

 客户端代码:

#include"brand.h"
int main()
{
	Brand* mobileA = new BrandA();
	mobileA->setHandsoft(new Game());
	mobileA->run();

	Brand* mobileB = new BrandB();
	mobileB->setHandsoft(new Comunication());
	mobileB->run();
	return 0;
}

 测试效果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值