文章目录
1.面向对象中有哪些设计原则?
2.开闭原则,哪些原则与它相关,其关系
3.里氏替换原则原则
#include <iostream>
using namespace std;
class ZooShow {
public:
void Show() {
if (Show0()) {
PlayGame();
}
Show1();
Show2();
Show3();
}
private:
void PlayGame() {
cout << "after Show0, then play game" << endl;
}
protected:
virtual bool Show0() {
cout << "show0" << endl;
if (!expired) {
return true;
}
return false;
}
virtual void Show2() {
cout << "show2" << endl;
}
virtual void Show1() {
}
virtual void Show3() {
}
bool expired;
};
class ZooShowEx1 : public ZooShow {
protected:
virtual bool Show0() {
cout << "ZooShowEx1 show0" << endl;
if (! expired) { //里氏替换
return true;
}
return false;
}
virtual void Show2() {
}
};
4.迪米特原则
5.依赖倒置原则
6.单例模式多线程
单线程环境下的单例模式:
class Singleton {
public:
static Singleton *GetInstance() {
if (_instance == nullptr) {
_instance = new Singleton();
std::atexit(Destructor);
}
return _instance;
}
private:
static void Destructor() {
if (_instance != nullptr) {
delete _instance;
_instance = nullptr;
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singleton &clone) {}
Singleton & operator = (const Singleton &) {}
static Singleton *_instance;
};
Singleton * Singleton::_instance = nullptr;
多线程环境互斥锁
#include <mutex>
class Singleton {
public:
static Singleton *GetInstance() {
// std::lock_guard<std::mutex> lock(_mutex); //加锁粒度大
if (_instance == nullptr) {
std::lock_guard<std::mutex> lock(_mutex);
if (_instance == nullptr) {
_instance = new Singleton(); //多线程环境下编译器和CPU对程序进行优化
// 1. 分配内存
// 2. 调用构造函数
// 3. 返回指针,赋值运算
// 多线程环境下可能会优化为1 3 2
std::atexit(Destructor);
}
}
return _instance;
}
private:
static void Destructor() {
if (_instance != nullptr) {
delete _instance;
_instance = nullptr;
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singleton &clone) {}
Singleton & operator = (const Singleton &) {}
static Singleton *_instance;
static std::mutex _mutex;
};
Singleton * Singleton::_instance = nullptr;
std::mutex Singleton::_mutex;
#include <mutex>
#include <atomic>
class Singleton {
public:
static Singleton *GetInstance() {
Singleton *temp = _instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
if (temp == nullptr) {
std::lock_guard<std::mutex> lock(_mutex);
temp = _instance.load(std::memory_order_relaxed);
if (temp == nullptr) {
temp = new Singleton(); //多线程环境下编译器和CPU对程序进行优化
std::atomic_thread_fence(std::memory_order_release);
_instance.store(temp, std::memory_order_relaxed);
// 1. 分配内存
// 2. 调用构造函数
// 3. 返回指针,赋值运算
// 多线程环境下可能会优化为1 3 2
std::atexit(Destructor);
}
}
return temp;
}
private:
static void Destructor() {
Singleton *temp = _instance.load(std::memory_order_relaxed);
if (temp != nullptr) {
delete temp;
temp = nullptr;
_instance.store(temp, std::memory_order_relaxed);
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singleton &clone) {}
Singleton & operator = (const Singleton &) {}
static std::atomic<Singleton *> _instance;
static std::mutex _mutex;
};
std::atomic<Singleton *> Singleton::_instance;
std::mutex Singleton::_mutex;
7.什么是工厂模式?什么是抽象工厂?
7.1 简单工厂模式
- 定义:根据参数的不同返回不同类的实例,被创建的实例通常具有共同的基类。
- 结构:
- 工厂:根据客户提供的具体产品类的参数,创建具体产品的实例。
- 抽象产品:具体产品类的基类,包含创建产品的公共方法。
- 具体产品:抽象产品的派生类,特定产品的实现方法。
- 优点:
- 工厂类提供创建产品的具体方法,客户不必参与创建过程。
- 客户只需要知道对应产品参数即可。
- 缺点:
- 客户增加产品时,需要修改工厂类逻辑,违背开闭原则。
- 客户增加产品时,需要修改工厂类逻辑,违背开闭原则。
7.2 工厂方法模式
- 定义:工厂类中针对不同的产品设计不同的工厂,每种工厂是生成特定的产品(解决简单工厂模式存在的不足)。定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
- 结构:
- 抽象工厂:所有生产具体产品的工厂类的基类,提供工厂类的公共方法。
- 具体工厂:生产具体的产品工厂类。
- 抽象产品:所有产品的基类,提供产品类的公共方法。
- 具体产品:具体的产品类。
- 优点:
- 工厂方法用于创建客户所需产品,同时向客户隐藏细节,用户只需关心所需产品对应的工厂;
- 工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键;
- 新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。
- 缺点:
- 添加新的产品时,引入新的产品工厂,增加了系统复杂度;
- 工厂和产品中都引入抽象层,增加了系统的抽象层次。
7.3 抽象工厂模式
- 定义:一个工厂不止生产一种产品,生产一类产品。提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 结构:
- 抽象工厂:所有生产具体产品的工厂类的基类,提供工厂类的公共方法。
- 具体工厂:生产具体的产品工厂类,可以生产多种同类相关的产品。
- 抽象产品:所有产品的基类,提供产品类的公共方法。
- 具体产品:具体的产品类。
- 优点:
- 工厂方法用于创建客户所需产品,同时向客户隐藏细节,用户只需关心所需产品对应的工厂;
- 新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。
- 缺点:
- 添加新产品时需要修改抽象层代码,对原有系统改动较大。
#include <string>
// 实现导出数据的接口
class IExport {
public:
virtual bool Export(const std::string &data) = 0;
virtual ~IExport() {};
};
class ExportXml : public IExport {
public:
virtual bool Export(const std::string &data) {
return true;
}
};
class ExportJson : public IExport {
public:
virtual bool Export(const std::string &data) {
return true;
}
};
class ExportTxt : public IExport {
public:
virtual bool Export(const std::string &data) {
return true;
}
};
class IExportFactory {
public:
IExportFactory() {
_export = nullptr;
}
virtual ~IExportFactory() {
if (_export) {
delete _export;
_export = nullptr;
}
}
bool Export(const std::string &data) {
if (_export == nullptr) {
_export = NewExport();
}
return _export->Export(data);
}
protected:
virtual IExport * NewExport(/*---*/) = 0;
private:
IExport* _export;
};
class ExoortXmlFactory : public IExportFactory {
protected:
virtual IExport * NewExport(/*---*/) {
// 可能有其它很多操作
IExport * temp = new ExportXml();
return temp;
}
};
class ExoortJsonFactory : public IExportFactory {
protected:
virtual IExport * NewExport(/*---*/) {
// 可能有其它很多操作
IExport * temp = new ExportJson();
return temp;
}
};
class ExoortTxtFactory : public IExportFactory {
protected:
virtual IExport * NewExport(/*---*/) {
// 可能有其它很多操作
IExport * temp = new ExportTxt();
return temp;
}
};
int main() {
IExportFactory *factory = new ExportTxtFactory();
factory->Export("hello world");
return 0;
}
8.什么是代理模式?应用场景是什么?
class ISsubject {
public:
virtual void Handle() = 0;
virtual ~ISsubject() {}
};
class RealSubject : public ISsubject {
public:
virtual void Handle() {
}
};
// 保护代理
class Proxy1 : public ISsubject {
public:
Proxy1(ISsubject * subject) : _subject(subject) {}
virtual void Handle() {
// 在访问RealSubject 之前一些处理
// if (不满足条件)
// return;
_subject->Handle();
count++;
// 在访问RealSubject 之后做一些处理
}
private:
ISsubject * _subject;
static int count;
};
int Proxy1::count = 0;
// 远程代理
class Proxy2 : public ISsubject {
public:
virtual void Handle() {
// 在访问RealSubject之前做一些特殊处理
// 发送数据到远端 网络处理 同步非阻塞 ntyco c协程
// IResult * val = rpc->call("RealSubject", "Handle");
// 在访问RealSubject之后做一些处理
}
private:
/*void callback(IResult * val) {
// 在访问RealSubject 之后做一些处理
}
*/
};
// 虚代理
class Proxy3 : public ISsubject {
public:
Proxy1(ISsubject *subject) : _subject(subject), _loaded(false) {}
virtual void Handle() {
if (! _loaded) {
_loaded = true;
//加载资源
}
_subject->Handle();
}
private:
ISsubject* _subject;
bool _loaded;
};
9.什么是装饰器模式?应用模式是什么?
#include <iostream>
using namespace std;
class Context {
public:
bool isMgr;
// User user;
// double groupsale;
};
class CalcBonus {
public:
CalcBonus(CalcBonus * c = nullptr) : cc(c) {}
virtual double Calc(Context &ctx) {
return 0.0;
}
virtual ~CalcBonus() {}
protected:
CalcBonus* cc;
};
class CalcMouthBonus : public CalcBonus {
public:
CalcMouthBonus(CalcBonus * c) : CalcBonus(c) {}
virtual double Calc(Context &ctx) {
double mbonus /*计算自己的*/;
return mbonus + cc->Calc(ctx);
}
};
class CalcSumBonus : public CalcBonus {
public:
CalcSumBonus(CalcBonus * c) : CalcBonus(c) {}
virtual double Calc(Context &ctx) {
double mbonus /*计算自己的*/;
return mbonus + cc->Calc(ctx);
}
};
class CalcCycleBonus : public CalcBonus {
public:
CalcCycleBonus(CalcBonus * c) : CalcBonus(c) {}
virtual double Calc(Context &ctx) {
double mbonus /*计算自己的*/;
return mbonus + cc->Calc(ctx);
}
};
int main() {
Context ctx1;
CalcBonus *base = new CalcBonus();
CalcBonus *cb2 = new CalcSumBonus(base);
CalcBonus *cb1 = new CalcMouthBonus(cb2);
cb2->Calc(ctx1);
return 0;
}
10.什么是组合模式?应用场景是什么?
class IComponent {
public:
IComponent(/* args */);
~IComponent();
virtual void Execute() = 0;
virtual void AddChild(IComponent *ele) {}
virtual void RemoveChild(IComponent *ele) {}
};
class Leaf : public IComponent {
public:
virtual void Execute() {
cout << "leaf execute" << endl;
}
};
class Composite : public IComponent {
private:
std::list<IComponent *> _list;
public:
virtual void AddChild(IComponent *ele) {
//
}
virtual void RemoveChild(IComponent *ele) {
}
virtual void Execute() {
for (auto iter = _list.begin(); iter != _list.end(); iter ++) {
iter->Execute();
}
}
};
11.什么是责任链模式?应用场景是什么?
12.什么是模板方法? 应用场景是什么?
13.什么是策略模式?应用场景是什么?
14.什么是观察者模式?应用场景是什么?
参考
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,点击立即学习:https://course.0voice.com/v1/course/intro?courseId=5&agentId=0