【算法救命班-第一期】 设计模式大全解 · 可以直接背
用的都是比较简单的例子,我觉得设计模式代码这块大致浏览一下,背背就可以啦~不用细看,收藏起来,面试之前大致浏览一下就行,出了那几个常考的我觉得基本上不会让你手撕的,看看常考的那几个设计模式会手撕就行
一、设计模式种类
分类 | 类模式模式 | 对象模式 |
创建型模式 | 工厂方法 | 单例、原型、 抽象工厂、建造者 |
结构型模式 | (类)适配器 | 代理、(对象)适配器、 桥接、装饰、外观、 享元、组合 |
行为型模式 | 模板方法、解释器 | 策略、命令、职责链、 状态、观察者、中介者、 迭代器、访问者、备忘录 |
二、设计模式原则: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人填写的调查问卷,定价取了平均值