【算法救命班-第一期】 设计模式大全解 · 可以直接背
用的都是比较简单的例子,我觉得设计模式代码这块大致浏览一下,背背就可以啦~不用细看,收藏起来,面试之前大致浏览一下就行,出了那几个常考的我觉得基本上不会让你手撕的,看看常考的那几个设计模式会手撕就行
一、设计模式种类
| 分类 | 类模式模式 | 对象模式 |
| 创建型模式 | 工厂方法 | 单例、原型、 抽象工厂、建造者 |
| 结构型模式 | (类)适配器 | 代理、(对象)适配器、 桥接、装饰、外观、 享元、组合 |
| 行为型模式 | 模板方法、解释器 | 策略、命令、职责链、 状态、观察者、中介者、 迭代器、访问者、备忘录 |
二、设计模式原则:7种(6+1)
- 单一职责原则 SRP:一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分
- 优点:
- 降低类的复杂度。一个类只负责一项职责,其逻辑肯定要比负责多项职责简单得多。
- 提高类的可读性。复杂性降低,自然其可读性会提高。
- 提高系统的可维护性。可读性提高,那自然更容易维护了。
- 变更引起的风险降低。变更是必然的,如果单一职责原则遵守得好,当修改一个功能时,可以显著降低对其他功能的影响。
- 降低类的复杂度。一个类只负责一项职责,其逻辑肯定要比负责多项职责简单得多。
- 优点:
- 开放封闭原则 OCP:软件实体应当对扩展开放,对修改关闭
- 只需要对拓展的代码测试
- 提高了代码可复用性,因为粒度小
- 提高可维护性,利于扩展
- 只需要对拓展的代码测试
- 依赖倒置原则 DIP:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象
- 它的主要目的是为了降低耦合性,它一般通过反射和配置文件来实现的
- 核心思想是:要面向接口编程,不要面向实现编程。
- 它的主要目的是为了降低耦合性,它一般通过反射和配置文件来实现的
- 里氏替换原则 LSP:继承必须确保超类所拥有的性质在子类中仍然成立
- 作用:
- 里氏替换原则是实现开闭原则的重要方式之一。
- 它克服了继承中重写父类造成的可复用性变差的缺点。
- 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
- 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。
- 里氏替换原则是实现开闭原则的重要方式之一。
- 作用:
- 接口隔离原则 ISP:尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法
- 优点:
- 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
- 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。
- 如果接口的粒度大小定义合理,能够保证系统的稳定性;但是,如果定义过小,则会造成接口数量过多,使设计复杂化;如果定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险。
- 使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义。
- 能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码。
- 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
- 优点:
- 合成复用原则 CRP:它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现
- 迪米特法则:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。
- 单一职责原则和接口隔离原则的区别
- 单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。
- 单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节; 而接口隔离原则主要约束接口,主要针对抽象,针对程序整体框架的构建。
- 单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。
三、常用设计模式代码:
1、单例模式:
1.1-饿汉模式:指全局的单例实例在类加载时就被构建
class Singleton
{
public:
static Singleton &getObject()//给外界的唯一接口
{
return instance;
}
void set(int t)
{
data = t;
}
void print()
{
cout << "数据为 == " << data << endl;
}
//其他成员函数
private:
Singleton(){};
~Singleton(){};
Singleton(const Singleton &rhs); //拷贝构造函数
Singleton &operator=(const Singleton &rhs); //拷贝赋值运算符
Singleton(const Singleton &&rhs); //移动构造函数
Singleton &operator=(const Singleton &&rhs); //移动赋值运算符
static Singleton instance;
int data;
};
Singleton Singleton::instance; //注意需要在类外定义
int main(void)
{
Singleton::getObject().set(233);
Singleton::getObject().print();
return 0;
}
1.2-懒汉模式:指全局的单例实例在第一次被使用时构建
class Singleton
{
public:
static Singleton &getObject() //给外界的唯一接口
{
static Singleton instance; //staic 离开函数仍然存在
return instance;
}
void set(int t)
{
data = t;
}
void print()
{
cout << "数据为 == " << data << endl;
}
//其他成员函数
private:
Singleton(){};
~Singleton(){};
Singleton(const Singleton &rhs); //拷贝构造函数
Singleton &operator=(const Singleton &rhs); //拷贝赋值运算符
Singleton(const Singleton &&rhs); //移动构造函数
Singleton &operator=(const Singleton &&rhs); //移动赋值运算符
int data;
};
int main(void)
{
Singleton::getObject().set(23333333);
Singleton::getObject().print();
return 0;
}
2、原型模式:
#include <iostream>
using namespace std;
/*抽象原型类*/
class Car
{
protected:
int id;
char name[10];
public:
virtual Car* Clone() = 0;
virtual void Show() = 0;
};
/*具体原型类*/
class CarTypeA :public Car
{
public:
CarTypeA(const char* name_input)
{
strcpy(name, name_input);
this->id = 0;
cout << "Construction....." << endl;
}
CarTypeA(const CarTypeA& other)
{
cout << "Copy Construction..." << endl;
this->id = other.id;
this->id++;
strcpy(this->name, other.name);
}
virtual CarTypeA* Clone()
{
CarTypeA* tmp = new CarTypeA(*this);
return tmp;
}
void Show()
{
cout << "Car id == " << id << " name == " << name << endl;
}
~CarTypeA()
{
cout << "Deconstruction CarTypeA" << endl;
}
};
int main()
{
Car *car1 = new CarTypeA("Porsche");
Car *car2 = car1->Clone();
Car *car3 = car2->Clone();
car1->Show();
car2->Show();
car3->Show();
return 0;
}
3.简单工厂模式
// 创建工厂
class OperatorFactory{
public:
AbstractCalculator* creatOperate(string str){
AbstractCalculator *oper = NULL;
if(str == "+"){
oper = new(ADDCalculator);
}else if (str == "-"){
oper= new(SUbCalculator);
}else if (str == "*"){
oper = new(MulCalculator);
}else if (str == "/"){
oper = new(DivCalculator);
}else{
cout << "false!!!!!" << endl;
}
return oper;
}
};
// 主函数
int main(){
AbstractCalculator *oper;
OperatorFactory factory;
oper = factory.creatOperate("+");
oper->m_Num1 = 1999;
oper->m_Num2 = 7234.44;
cout << oper->m_Num1 << " + " << oper->m_Num2 << " = " << oper->getResult() << endl;
return 0;
}
4.工厂方法模式
// 创建一个工厂接口
class IOperatorFactory{
public:
virtual AbstractCalculator* createOperate() = 0;
};
//加减乘除各建一个具体工厂实现这个接口
class AddFactory: public IOperatorFactory{
public:
AbstractCalculator* createOperate(){
return new ADDCalculator;
}
};
class SubFactory: public IOperatorFactory{
public:
AbstractCalculator* createOperate(){
return new SUbCalculator;
}
};
class MulFactory: public IOperatorFactory{
public:
AbstractCalculator* createOperate(){
return new MulCalculator;
}
};
class DivFactory: public IOperatorFactory{
public:
AbstractCalculator* createOperate(){
return new DivCalculator;
}
};
// 主函数
int main(){
AbstractCalculator *oper;
IOperatorFactory *factory = new AddFactory;
oper = factory->createOperate();
oper->m_Num1 = 1999;
oper->m_Num2 = 7234.44;
cout << oper->m_Num1 << " + " << oper->m_Num2 << " = " << oper->getResult() << endl;
return 0;
}
5.抽象工厂模式
//抽象产品
//抽象产品
class Product
{
public:
virtual void show()=0;
};
//具体产品
//具体产品1
class ConProduct1:public Product
{
public:
void show()
{
cout<<"小米手机生产完成"<<endl;
}
};
//具体产品2
class ConProduct2:public Product
{
public:
void show()
{
cout<<"电脑生产完成"<<endl;
}
};
//抽象工厂
class Factory
{
public:
//这里只能返回一个抽象类的指针,抽象类指针不能返回实体
virtual Product *newProduct()=0;
};
//具体工厂
//具体工厂1,实现产品1的生产
class ConFactory1:public Factory
{
public:
Product *newProduct()
{
cout<<"手机厂生产手机"<<endl;
}
return new ConProduct1();
};
//具体工厂2,实现产品2的生产
class ConFactory2:public Factory
{
public:
Product *newProduct()
{
cout<<"电脑厂生产电脑"<<endl;
}
return new ConProduct2();
};
//主函数
int main()
{
Product *p1=new ConProduct1();
Product *p2=new ConProduct2();
Fatory *q1=new ConFatory1();
Fatory *q2=new ConFatory2();
p1=q1->newProduct();
p1->show();
p2=q2->newProduct();
p2->show();
return 0;
} 6.建造者模式
//建造者模式示例代码
#include<iostream>
using namespace std;
class Builder
{
public:
virtual void buildHead() = 0;
virtual void buildBody() = 0;
virtual void buildArm() = 0;
virtual void buildLeg() = 0;
};
class ThinBuilder :public Builder
{
public:
void buildHead()
{
cout << "Build Thin Head!" << endl;
}
void buildBody()
{
cout << "Build Thin Body!" << endl;
}
void buildArm()
{
cout << "Build Thin Arms!" << endl;
}
void buildLeg()
{
cout << "Build Thin Legs!" << endl;
}
};
class FatBuilder :public Builder
{
public:
void buildHead()
{
cout << "Build Fat Head!" << endl;
}
void buildBody()
{
cout << "Build Fat Body!" << endl;
}
void buildArm()
{
cout << "Build Fat Arms!" << endl;
}
void buildLeg()
{
cout << "Build Fat Legs!" << endl;
}
};
class Director
{
Builder *pBuilder;
public:
Director(Builder *iBuilder)
{
pBuilder = iBuilder;
}
void Create()
{
pBuilder->buildHead();
pBuilder->buildBody();
pBuilder->buildArm();
pBuilder->buildLeg();
}
};
//客户端调用
int main()
{
cout << "Builder DP Test!" << endl;
Builder *pBuilderInstance = new FatBuilder();
Director dir(pBuilderInstance);
dir.Create();
system("pause");
return 0;
} 7.代理模式
#include<iostream>
using namespace std;
//抽象主题角色
class subject
{
public:
virtual void Request()=0{}
};
//真实主题角色
class Consubject:public subject
{
public:
void Requset();//实现了在抽象主题角色中定义的方法
};
void Consubject::Request() //重载
{
cout<<"ConRequest"<<endl;
}
//代理主题角色
class Proxy
{
public:
Proxy(){}
Proxy(subject* sub){m_sub=sub;} //代理主题角色中定义了一个真实主题角色对象
~Proxy(){delete m_sub;}
void Request() //代理主题角色也实现了抽象主题角色的方法
{
cout<<"Proxy REQ"<<endl;
m_sub->Request();//代理主题角色调用 真实角色的业务方法
}
private:
subject* m_sub;
};
void main()
{
subject* sub=new Consubject();//真实主题角色对象
Proxy* p=new Proxy(sub);//d定义代理主题对象
p->Request();
} 8.适配器模式
#include <iostream>
#include <memory>
#include <string>
class Target
{
public:
virtual bool NewRequest(const int value)
{
std::cout << "Calling new request method!" << std::endl;
return true;
}
virtual ~Target(){}
};
class Adaptee
{
public:
bool OldRequest(const std::string& strValue)
{
std::cout << "Calling old request method!" << std::endl;
return true;
}
};
class Adaptor : public Target
{
private:
std::shared_ptr<Adaptee> m_smartAdaptee;
public:
Adaptor(std::shared_ptr<Adaptee> adaptee)
{
m_smartAdaptee = std::move(adaptee);
}
bool NewRequest(const int value)
{
std::cout << "I'm new request method" << std::endl;
std::string strValue = std::to_string(value);
m_smartAdaptee->OldRequest(strValue);
return true;
}
};
int main()
{
std::shared_ptr<Target> target(new Adaptor(std::make_shared<Adaptee>()));
target->NewRequest(1);
system("pause");
return 0;
}
9.桥接模式
#include <iostream>
#include <memory>
#include <boost\mpl\vector.hpp>
#include <boost\mpl\for_each.hpp>
//*****************Bridge Pattern*******************
//抽象手机软件
class HandsetSoft
{
public:
virtual void Run() = 0;
};
class HandsetGame : public HandsetSoft
{
public:
void Run()
{
std::cout << "运行手机游戏!" << std::endl;
}
};
class HandsetAddressList : public HandsetSoft
{
public:
void Run()
{
std::cout << "运行手机通讯录!" << std::endl;
}
};
class HandsetMP3 : public HandsetSoft
{
public:
void Run()
{
std::cout << "运行手机MP3!" << std::endl;
}
};
//抽象手机品牌
class HandsetBrand
{
protected:
std::shared_ptr<HandsetSoft> smartSoft;
public:
void SetHandsetSoft(std::shared_ptr<HandsetSoft> ptrSoft)
{
smartSoft = ptrSoft;
}
virtual void Run() = 0;
};
//手机品牌:M
class HandsetBrandM : public HandsetBrand
{
public:
void Run()
{
std::cout << "\n M品牌手机:";
smartSoft->Run();
}
};
//手机品牌: N
class HandsetBrandN : public HandsetBrand
{
public:
void Run()
{
std::cout << "\n N品牌手机:";
smartSoft->Run();
}
};
//****************Test******************************
struct HandsetSoftTester
{
public:
static std::shared_ptr<HandsetBrand> smartHB;
template<typename T>
void operator()(T)
{
if (smartHB != NULL)
{
smartHB->SetHandsetSoft(std::make_shared<T>());
smartHB->Run();
}
}
};
std::shared_ptr<HandsetBrand> HandsetSoftTester::smartHB = NULL;
struct HandsetBrandTester
{
template<typename T>
void operator()(T)
{
typedef boost::mpl::vector<HandsetGame, HandsetAddressList, HandsetMP3> HandsetSoftParams;
std::shared_ptr<HandsetBrand> smartHB = std::make_shared<T>();
HandsetSoftTester::smartHB = smartHB;
boost::mpl::for_each<HandsetSoftParams>(HandsetSoftTester());
}
};
int main()
{
typedef boost::mpl::vector<HandsetBrandM, HandsetBrandN> HandsetBrandParams;
boost::mpl::for_each<HandsetBrandParams>(HandsetBrandTester());
system("pause");
return 0;
}
10.装饰器模式
class Car
{
public:
virtual void show() = 0;
};
// 三个实体的汽车类
class Bmw :public Car
{
public:
void show()
{
cout << "这是一辆宝马汽车,配置有:基本配置";
}
};
class Audi :public Car
{
public:
void show()
{
cout << "这是一辆奥迪汽车,配置有:基本配置";
}
};
class Benz :public Car
{
public:
void show()
{
cout << "这是一辆奔驰汽车,配置有:基本配置";
}
};
// 装饰器1 定速巡航
class Decorator01 :public Car
{
public:
Decorator01(Car* p) :pCar(p) {}
void show()
{
pCar->show();
cout << ",定速巡航";
}
private:
Car* pCar;
};
// 装饰器2 自动刹车
class Decorator02 :public Car
{
public:
Decorator02(Car* p) :pCar(p) {}
void show()
{
pCar->show();
cout << ",自动刹车";
}
private:
Car* pCar;
};
// 装饰器3 定速巡航
class Decorator03 :public Car
{
public:
Decorator03(Car* p) :pCar(p) {}
void show()
{
pCar->show();
cout << ",车道偏离";
}
private:
Car* pCar;
};
11.外观模式
#include "CMakeProject1.h"
using namespace std;
//子系统
class TV {
public:
void tVOn() {
cout << "turn on the television!" << endl;
}
void tVOff() {
cout << "turn off the television!" << endl;
}
};
//子系统
class Conditioner {
public:
void conditionerOn() {
cout << "turn on the conditioner!" << endl;
}
void conditionerOff() {
cout << "turn off the conditioner!" << endl;
}
};
//外观类 将客户端的请求代理给适当的子系统对象
class ElectricSwich
{
public:
ElectricSwich();
~ElectricSwich();
void electricOn() {
tv->tVOn();
conditioner->conditionerOn();
}
void electricOff() {
tv->tVOff();
conditioner->conditionerOff();
}
private:
TV* tv;
Conditioner* conditioner;
};
ElectricSwich::ElectricSwich() {
tv = new TV;
conditioner = new Conditioner;
}
ElectricSwich::~ElectricSwich() {
delete tv;
delete conditioner;
}
int main()
{
ElectricSwich* electricSwich = new ElectricSwich;
electricSwich->electricOn();
electricSwich->electricOff();
delete electricSwich;
return 0;
} 12.享元模式
class Flyweight
{
public:
virtual void Operation() = 0;
};
class ConcreteFlyweight : public Flyweight
{
public:
void Operation() {};
};
class UnshareConcreteFlyweight : public Flyweight
{
public:
void Operation() {};
};
class FlyweightFactory
{
public:
FlyweightFactory() { confly = nullptr; uncfly = nullptr; }
~FlyweightFactory() { delete confly; delete uncfly; }
void GetFlyweight()
{
if (confly == nullptr)
confly = new ConcreteFlyweight();
confly->Operation();
if (uncfly == nullptr)
uncfly = new UnshareConcreteFlyweight();
uncfly->Operation();
}
private:
Flyweight* confly;
Flyweight* uncfly;
};
int main()
{
FlyweightFactory flyfac;
flyfac.GetFlyweight();
return 0;
} 13.组合模式
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Company
{
protected:
string m_name;
public:
Company( string name ) : m_name(name)
{}
virtual ~Company()
{}
virtual void Add( Company* c) = 0;
virtual void Remove( Company* c) = 0;
virtual void Display( int depth ) = 0;
virtual void LineOfDuty() = 0;
};
class ConcreteCompany : public Company
{
private:
list<Company*>children;
public:
ConcreteCompany(string name) : Company(name)
{}
void Add(Company* c)
{
children.push_back(c);
}
void Remove(Company* c)
{
children.remove(c);
}
void Display(int depth)
{
for(int i=0; i < depth; i++)
{
cout<<"-";
}
cout<<m_name<<endl;
list<Company*>::iterator ite = children.begin();
for( ; ite != children.end(); ite++ )
{
(*ite)->Display(depth+2);
}
}
void LineOfDuty()
{
list<Company*>::iterator ite = children.begin();
for( ; ite != children.end(); ite++ )
{
(*ite)->LineOfDuty();
}
}
};
class HRDepartment : public Company
{
public:
HRDepartment( string name ) : Company(name)
{}
void Add( Company* c )
{}
void Remove(Company* c)
{}
void Display( int depth )
{
for(int i=0; i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
}
void LineOfDuty()
{
cout<<m_name<<"员工招聘培训管理"<<endl;
}
};
class FinanceDepartment : public Company
{
public:
FinanceDepartment( string name ) : Company(name)
{}
void Add( Company* c )
{}
void Remove(Company* c)
{}
void Display( int depth )
{
for(int i=0; i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
}
void LineOfDuty()
{
cout<<m_name<<"公司财务收支管理"<<endl;
}
};
int main()
{
ConcreteCompany root("北京总公司");
root.Add( new HRDepartment("总公司人力资源部") );
root.Add( new FinanceDepartment("总公司财务部") );
ConcreteCompany comp("上海华东分公司");
comp.Add( new HRDepartment("华东分公司人力资源部") );
comp.Add( new FinanceDepartment("华东分公司财务部") );
root.Add(&comp);
ConcreteCompany comp1("南京办事处");
comp1.Add( new HRDepartment("南京办事处人力资源部") );
comp1.Add( new FinanceDepartment("南京办事处财务部") );
comp.Add(&comp1);
ConcreteCompany comp2("杭州办事处");
comp2.Add( new HRDepartment("杭州办事处人力资源部") );
comp2.Add( new FinanceDepartment("杭州办事处财务部") );
comp.Add(&comp2);
cout<<"结构图"<<endl;
root.Display(1);
return 0;
} 14.
模板方法模式15.
策略模式16.命令模式
#include <iostream>
#include <list>
using namespace std;
// Receiver类(请求接收者),知道如何实施与执行一个与请求相关的操作:
class Receiver {
public:
void Action() {
cout << "Receiver" << endl;//实现action()方法,用于执行与请求相关的操作
}
};
// Command类(抽象命令类),用来声明执行操作的接口
class Command {
public:
virtual void Excute() = 0;
virtual void setReceiver(Receiver* r) = 0;
virtual ~Command(){};
};
// ConcreteCommand类(具体命令类),绑定一个Receiver,调用其相应操作以实现Excute:
class ConcreteCommand : public Command {
private:
Receiver* receiver;
public:
void setReceiver(Receiver* r) {
receiver = r;
}
void Excute() {
//cout << "ConcreteCommand" << endl;
receiver->Action();//调用接受者请求响应方法
}
};
// 请求发送者,要求该命令执行这个请求:
class Invoker {
private:
list<Command* > commands;
public:
void setCommand(Command* c) {//通过构造函数注入或设置注入的方式运行时传入具体命令类对象
commands.push_back(c);
}
void Notify() {
for (auto c = commands.begin(); c != commands.end(); c++) {
(*c)->Excute();//调用excute()
}
}
};
// 客户端实现代码:
int main() {
Command* c = new ConcreteCommand();
Receiver* r = new Receiver();
c->setReceiver(r);//第一步:请求接受者作为构造函数的参数来创建具体的command对象
Invoker i;
i.setCommand(c);//第二步:将具体Command对象保存在请求调用者中
i.Notify(); // 第三步请求调用者调用Command对象的excute()方法,后者再调用请求接受者的action()方法完成对请求的处理
delete r;
delete c;
return 0;
} 17. 责任链模式
18.
状态模式19.观察者模式
#include <iostream>
#include <list>
using namespace std;
/*抽象观察者*/
class Observer
{
public:
virtual void Update(int) = 0;
};
/*抽象目标*/
class Subject
{
public:
virtual void Attach(Observer *) = 0; //附加观察者
virtual void Detach(Observer *) = 0; //移除观察者
virtual void Notify() = 0; //通知观察者
};
/*具体观察者*/
class ConcreteObserver : public Observer
{
public:
ConcreteObserver(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
/*具体观察者2*/
class ConcreteObserver2 : public Observer
{
public:
ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver2 get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
/*具体目标*/
class ConcreteSubject : public Subject
{
public:
void Attach(Observer *pObserver);
void Detach(Observer *pObserver);
void Notify();
void SetState(int state)
{
m_iState = state;
}
private:
std::list<Observer *> m_ObserverList;//观察者列表
int m_iState;
};
//附加观察者
void ConcreteSubject::Attach(Observer *pObserver)
{
m_ObserverList.push_back(pObserver);
}
//移除观察者
void ConcreteSubject::Detach(Observer *pObserver)
{
m_ObserverList.remove(pObserver);
}
//通知观察者
void ConcreteSubject::Notify()
{
std::list<Observer *>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end())
{
(*it)->Update(m_iState);
++it;
}
}
int main()
{
// Create Subject 目标实例化
ConcreteSubject *pSubject = new ConcreteSubject();
// Create Observer 创建观察者
Observer *pObserver = new ConcreteObserver(pSubject);
Observer *pObserver2 = new ConcreteObserver2(pSubject);
// Change the state
pSubject->SetState(2);
// Register the observer
pSubject->Attach(pObserver);
pSubject->Attach(pObserver2);
pSubject->Notify();
// Unregister the observer
pSubject->Detach(pObserver);
pSubject->SetState(3);
pSubject->Notify();
delete pObserver;
delete pObserver2;
delete pSubject;
} 20.
中介者模式21.
迭代器模式22.访问者模式
访问者模式中对象结构存储了不同类型的元素对象,以提供不同访问者访问。访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。
相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同的方式访问。
(1)Visitor (抽象访问者)
抽象访问者为对象结构类中每一个具体元素类声明一个访问操作。
(2)ConcreteVisitor (具体访问者)
具体访问者实现了每个由抽象访问者声明的操作,每一个操作用于访问对象结构中一种元素类型的元素。
(3)Element(抽象元素)
抽象元素一般是抽象类或接口,定义一个accept()方法,该方法以一个抽象访问者作为参数。
(4)ConcreteElement (具体元素)
具体访问者实现了accept()方法,在其accept()
(5)ObjectStructure(对象结构)
对象结构是一个元素的集合,它用于存放元素对象,并且提供了遍历其内部元素的方法。
#include <iostream>
#include <vector>
using namespace std;
class ConcreteElementA;
class ConcreteElementB;
/*抽象访问者 声明了访问元素对象的方法,通常为每一种类型的元素对象都提供一个访问方法*/
class Visitor
{
public:
virtual void VisitConcreteElementA(ConcreteElementA *pElementA) = 0;
virtual void VisitConcreteElementB(ConcreteElementB *pElementB) = 0;
};
/*具体访问者 用于定义对不同类型元素对象的操作*/
class ConcreteVisitor1 : public Visitor
{
public:
void VisitConcreteElementA(ConcreteElementA *pElementA){
// 现在根据传进来的pElementA,可以对ConcreteElementA中的element进行操作
}
void VisitConcreteElementB(ConcreteElementB *pElementB){
// 现在根据传进来的pElementB,可以对ConcreteElementB中的element进行操作
}
};
/*具体访问者2*/
class ConcreteVisitor2 : public Visitor
{
public:
void VisitConcreteElementA(ConcreteElementA *pElementA){
}
void VisitConcreteElementB(ConcreteElementB *pElementB){
}
};
/*抽象元素类 声明accept()方法,用于接受访问者的访问*/
class Element
{
public:
virtual void Accept(Visitor *pVisitor) = 0;//accept用于接受访问者的访问
};
/*具体元素类 通过调用Visitor类的visit()方法实现对元素的访问*/
class ConcreteElementA : public Element
{
public:
void Accept(Visitor *pVisitor)//通过调用visitor对象的 visit()方法实现对元素对象的访问
{
pVisitor->VisitConcreteElementA(this);
}
};
/*具体元素类 */
class ConcreteElementB : public Element
{
public:
void Accept(Visitor *pVisitor)
{
pVisitor->VisitConcreteElementB(this);
}
};
// ObjectStructure类(对象结构类),能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素
class ObjectStructure
{
public:
void Attach(Element *pElement){
elements.push_back(pElement);
}
void Detach(Element *pElement)
{
vector<Element *>::iterator it = find(elements.begin(), elements.end(), pElement);
if (it != elements.end())
{
elements.erase(it);
}
}
void Accept(Visitor *pVisitor){
// 为每一个element设置visitor,进行对应的操作
for (vector<Element *>::const_iterator it = elements.begin(); it != elements.end(); ++it)
{
(*it)->Accept(pVisitor);
}
}
int main()
{
//实例化对象结构,用于存放元素对象,提供遍历其内部元素的方法
ObjectStructure *pObject = new ObjectStructure;
//实例化具体元素 并将创建好的元素放入对象结构中
ConcreteElementA *pElementA = new ConcreteElementA;
ConcreteElementB *pElementB = new ConcreteElementB;
pObject->Attach(pElementA);
pObject->Attach(pElementB);
//实例化访问者
ConcreteVisitor1 *pVisitor1 = new ConcreteVisitor1;
ConcreteVisitor2 *pVisitor2 = new ConcreteVisitor2;
//调用accept方法 来接受访问者对象的访问
pObject->Accept(pVisitor1);
pObject->Accept(pVisitor2);
if (pVisitor2) delete pVisitor2;
if (pVisitor1) delete pVisitor1;
if (pElementB) delete pElementB;
if (pElementA) delete pElementA;
if (pObject) delete pObject;
return 0;
}
23.备忘录模式
#include <iostream>
#include <memory>
//*****************Memo Pattern*****************
//备忘录类
class GameRoleMemento
{
private:
int vit;
int atk;
int def;
public:
GameRoleMemento(const int nVit, const int nAtk, const int nDef) : vit(nVit), atk(nAtk), def(nDef) {}
int GetVit() const
{
return vit;
}
int GetAtk() const
{
return atk;
}
int GetDef() const
{
return def;
}
};
//管理备忘录类
class RoleStateCaretaker
{
private:
std::shared_ptr<GameRoleMemento> smartMemento;
public:
void SetGameRoleMemento(std::shared_ptr<GameRoleMemento> pMemento)
{
smartMemento = pMemento;
}
std::shared_ptr<GameRoleMemento> GetGameRoleMemento() const
{
return smartMemento;
}
};
//游戏角色类
class GameRole
{
private:
int vit;//生命力
int atk;//攻击力
int def;//防御力
public:
GameRole(int nVit, int nAtk, int nDef) : vit(nVit), atk(nAtk), def(nDef) {}
GameRoleMemento* SaveState()
{
return new GameRoleMemento(vit, atk, def);
}
void DisplayState()
{
std::cout << "当前生命力:" << vit << ", 当前攻击力:" << atk << ", 当前防御力:" << def << std::endl;
}
void RecoveryState(const GameRoleMemento& memento)
{
vit = memento.GetVit();
atk = memento.GetAtk();
def = memento.GetDef();
}
void Fight()
{
vit = 0;
atk = 0;
def = 0;
}
};
//********************Test********************
int main()
{
std::cout << "大战Boss前" << std::endl;
std::shared_ptr<GameRole> lixiaoyao = std::make_shared<GameRole>(100, 100, 100);
lixiaoyao->DisplayState();
//保存进度
std::shared_ptr<RoleStateCaretaker> stateAdmin = std::make_shared<RoleStateCaretaker>();
stateAdmin->SetGameRoleMemento(std::shared_ptr<GameRoleMemento>(lixiaoyao->SaveState()));
std::cout << "\n大战后" << std::endl;
lixiaoyao->Fight();
lixiaoyao->DisplayState();
std::cout << "\n恢复到大战前:" << std::endl;
lixiaoyao->RecoveryState(*(stateAdmin->GetGameRoleMemento()));
lixiaoyao->DisplayState();
system("pause");
return 0;
}
24.解释器模式
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
#include <regex>
#include <set>
//***********************Interpreter Pattern******************
//抽象表达式类
class Expression
{
public:
virtual bool Interpret(const std::string& info) = 0;
};
//终结符表达式类
class TerminalExpressin : public Expression
{
private:
std::set<std::string> infos;
public:
TerminalExpressin(const std::vector<std::string> datas)
{
infos.insert(datas.begin(), datas.end());
}
bool Interpret(const std::string& info)
{
if (infos.find(info) != infos.end())
return true;
return false;
}
};
//非终结符表达式类
class AndExpression : public Expression
{
private:
std::shared_ptr<Expression> smartCity;
std::shared_ptr<Expression> smartPerson;
public:
AndExpression(std::shared_ptr<Expression> city, std::shared_ptr<Expression> person): smartCity(city), smartPerson(person){}
bool Interpret(const std::string& info)
{
std::regex pattern("的");
std::vector<std::string> results(std::sregex_token_iterator(info.begin(), info.end(), pattern, -1), std::sregex_token_iterator());
if (results.size() != 2)
{
std::cout << "输入解释信息有误,无法解析!" << std::endl;
return false;
}
return smartCity->Interpret(results[0]) && smartPerson->Interpret(results[1]);
}
};
//上下文全局信息类
class Context {
private:
std::vector<std::string> citys;
std::vector<std::string> persons;
std::shared_ptr<Expression> smartAndExpr;
public:
Context()
{
citys.push_back("成都");
citys.push_back("临沂");
persons.push_back("老人");
persons.push_back("儿童");
smartAndExpr = std::make_shared<AndExpression>(std::make_shared<TerminalExpressin>(citys), std::make_shared<TerminalExpressin>(persons));
}
void IsFree(const std::string& info)
{
if (smartAndExpr->Interpret(info))
{
std::cout << info << " , 您本次乘车免费" << std::endl;
}
else
{
std::cout << info << ", 您本次乘车扣费2¥" << std::endl;
}
}
};
//*****************************Test************************
int main()
{
std::shared_ptr<Context> bus = std::make_shared<Context>();
std::vector<std::string> passengers = { "成都的老人" , "成都的年轻人" , "成都的儿童" , "临沂的老人" , "临沂的年轻人" , "临沂的儿童" };
for (std::string passenger : passengers)
{
bus->IsFree(passenger);
}
system("pause");
return 0;
}
代码鹿 の【算法题】救命专栏 文章被收录于专栏
①【专栏内容】:按类别题型汇总、整理了大厂近四年面试中出现的经典算法题,做一个答案汇总与解析; ②【适用群体】:代码能力薄弱+没太有时间做算法的小伙伴;熟练coding先感受一下面试真题的小伙伴; ③【我的考虑】:这些题目来自近四年面经,我进行了总结和整理。面向面试编程,如果面试遇到了那就赚,没遇到你的代码能力通过这个练习得到了提升; ④【定价】:当时发布了个543人填写的调查问卷,定价取了平均值

查看19道真题和解析
