目录
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;
}