设计模式是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它是一套提高代码复用性,可维护性,可读性,稳健性以及安全性的解决方案
单一责任原则(Single Responsibility Principle)
开闭原则(Open Closed Principle)
里氏替换原则(Liskov Substitution Principle)
依赖倒置原则(Dependence Inversion Principle)
迪米特法则(Law of Demeter) 最少知道法则
接口隔离原则
从整体上理解六大设计原则,可以简要概括为一句话,用抽象构建框架,用实现扩展细节,具体到每一条设计原则,则对应一条注意事项
/* 饿汉单例模式 以空间换时间 */
class Singleton{
public:
static Singleton& getInstance() { return _eton; }
int getData() { return _data; }
private:
Singleton(int data = 99) : _data(data){}
~Singleton(){};
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
static Singleton _eton;
int _data;
};
Singleton Singleton::_eton;
int main() {
std::cout << Singleton::getInstance().getData() << std::endl;
return 0;
}
/* 懒汉单例模式 懒加载 -- 延时加载思想 -- 一个对象用的时候再实例化 */
// 这里介绍 作者提出的一种更加优雅简便的单例模式 Meyers Singleton int C++
// C++11后是线程安全的
class Singleton{
public:
static Singleton& getInstance() {
static Singleton _eton;
return _eton;
}
int getData() { return _data; }
private:
Singleton(int data = 99) : _data(data){}
~Singleton() {};
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
int _data;
};
int main() {
std::cout << Singleton::getInstance().getData() << std::endl;
return 0;
}
工厂模式是一种创建型的设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象不会对上层暴露创建逻辑,而是通过使用一个共同结构来指向新创建的对象,因此实现创建-使用的分离
工厂模式分为:
class Fruit{
public:
virtual void name() = 0;
private:
};
class Apple : public Fruit{
public:
void name() override{
std::cout << "I'm a apple" << std::endl;
}
};
class Banana : public Fruit{
public:
void name() override {
std::cout << "I'm a banana" << std::endl;
}
};
class FruitFactory {
public:
static std::shared_ptr<Fruit> create(const std::string &name) {
if (name == "苹果") {
return std::make_shared<Apple>();
} else {
return std::make_shared<Banana>();
}
}
};
int main() {
std::shared_ptr<Fruit> fruit = FruitFactory::create("苹果");
fruit->name();
fruit = FruitFactory::create("香蕉");
fruit->name();
return 0;
}
这个模式的结构和管理产品对象的方式非常简单,但是它的扩展性非常差,当我们需要新增产品的时候,就需要去修改工厂类新增一个类型的产品创造逻辑,违背了开闭原则
/* 工厂方法模式 */
class Fruit{
public:
virtual void name() = 0;
private:
};
class Apple : public Fruit{
public:
void name() override{
std::cout << "I'm a apple" << std::endl;
}
};
class Banana : public Fruit{
public:
void name() override {
std::cout << "I'm a banana" << std::endl;
}
};
class FruitFactory {
public:
virtual std::shared_ptr<Fruit> createFruit() = 0;
};
class AppleFactory : public FruitFactory {
public:
virtual std::shared_ptr<Fruit> createFruit() override {
return std::make_shared<Apple>();
}
};
class BananaFactory : public FruitFactory {
public:
virtual std::shared_ptr<Fruit> createFruit() override {
return std::make_shared<Banana>();
}
};
int main() {
std::shared_ptr<FruitFactory> ff(new AppleFactory());
std::shared_ptr<Fruit> fruit1 = ff->createFruit();
fruit1->name();
ff.reset(new BananaFactory());
std::shared_ptr<Fruit> fruit2 = ff->createFruit();
fruit2->name();
return 0;
}
工厂方法模式每次增减一个产品时,都需要增加一个具体的产品类和工厂类,这使得系统中类的个数成倍的增加,在一定程度上增加了系统的耦合度
#include
#include
/* 简单工厂模式 */
class Fruit{
public:
virtual void name() = 0;
private:
};
class Apple : public Fruit{
public:
void name() override{
std::cout << "I'm a apple" << std::endl;
}
};
class Banana : public Fruit{
public:
void name() override {
std::cout << "I'm a banana" << std::endl;
}
};
class Animal {
public:
virtual void name() = 0;
};
class Lamp : public Animal {
public:
virtual void name() override {
std::cout << "I'm a Lamp" << std::endl;
}
};
class Dog : public Animal {
public:
virtual void name() override {
std::cout << "I'm a dog" << std::endl;
}
};
class Factory {
public:
virtual std::shared_ptr<Fruit> getFruit(const std::string& name) = 0;
virtual std::shared_ptr<Animal> getAnimal(const std::string& name) = 0;
};
class FruitFactory : public Factory {
public:
virtual std::shared_ptr<Fruit> getFruit(const std::string& name) override{
if (name == "苹果") {
return std::make_shared<Apple>();
} else {
return std::make_shared<Banana>();
}
}
virtual std::shared_ptr<Animal> getAnimal(const std::string& name) override{
return std::shared_ptr<Animal>();
}
};
class AnimalFactory : public Factory {
public:
virtual std::shared_ptr<Fruit> getFruit(const std::string& name) override {
return std::shared_ptr<Fruit>();
}
virtual std::shared_ptr<Animal> getAnimal(const std::string& name) override {
if (name == "山羊") {
return std::make_shared<Lamp>();
} else {
return std::make_shared<Dog>();
}
}
};
class FactoryProducer {
public:
static std::shared_ptr<Factory> create(const std::string &name) {
if (name == "水果") {
return std::make_shared<FruitFactory>();
} else {
return std::make_shared<AnimalFactory>();
}
}
};
int main() {
std::shared_ptr<Factory> ff = FactoryProducer::create("水果");
std::shared_ptr<Fruit> fruit = ff->getFruit("苹果");
fruit->name();
fruit = ff->getFruit("香蕉");
fruit->name();
ff = FactoryProducer::create("动物");
std::shared_ptr<Animal> animal = ff->getAnimal("山羊");
animal->name();
animal = ff->getAnimal("小狗");
animal->name();
return 0;
}
抽象工厂模式适用于生产多个工厂系列产品衍生的设计模式,增加新的产品等级结构复杂,需要对原有系统进行较大修改,甚至需要修改抽象层代码,违背了开闭原则
建造者模式是一种创建型的设计模式,使用多个简单对象一步一步构建成一个复杂的对象,能够将一个复杂的对象的构建与它的表示分离,提供一种创建对象的最佳方式。主要用于解决对象的构建过于复杂的问题
建造者模式主要基于四个核心实现:
#include
#include
#include
/* 通过MacBook的构造理解建造者模式*/
class Computer{
public:
Computer(){};
void setBoard(const std::string &board) { _board = board; }
void setDisplay(const std::string &display) { _display = display; }
virtual void setOs() = 0;
void showParamaters() {
std::string param = "Computer Paramaters: \n";
param += "\tBoard: " + _board + "\n";
param += "\tDispaly: " + _display + "\n";
param += "\tOs: " + _os + "\n";
std::cout << param << std::endl;
}
protected:
std::string _board;
std::string _display;
std::string _os;
};
class MacBook : public Computer{
public:
virtual void setOs() override {
_os = "Mac OS x12";
}
};
class Builder {
public:
virtual void buildBoard(const std::string &board) = 0;
virtual void buildDisplay(const std::string &display) = 0;
virtual void buildOs() = 0;
virtual std::shared_ptr<Computer> build() = 0;
};
class MacBookBuilder : public Builder{
public:
MacBookBuilder() : _computer(new MacBook()) {}
void buildBoard(const std::string& board) {
_computer->setBoard(board);
}
void buildDisplay(const std::string& display) {
_computer->setDisplay(display);
}
void buildOs() {
_computer->setOs();
}
std::shared_ptr<Computer> build() {
return _computer;
}
private:
std::shared_ptr<Computer> _computer;
};
class Director {
public:
Director(Builder* builder) : _builder(builder) {}
void construct(const std::string& board, const std::string& display) {
_builder->buildBoard(board);
_builder->buildDisplay(display);
_builder->buildOs();
}
private:
std::shared_ptr<Builder> _builder;
};
int main() {
Builder * builder = new MacBookBuilder();
std::unique_ptr<Director> director(new Director(builder));
director->construct("华硕主板", "三星显示器");
std::shared_ptr<Computer> computer = builder->build();
computer->showParamaters();
return 0;
}
代理模式指的是代理控制对其他对象的访问,也就是代理对象控制对原对象的引用。在某些情况下,一个对象不适合或者不能直接被引用访问,而代理对象可以在客户端和目标对象之间起到中介作用
代理模式的结构包括一个是真正的你要访问的目标对象(目标类)、一个是代理对象。目标对象与代理对象实现同一个接口,先访问代理类再通过代理类访问目标对象。代理模式一般分为静态代理、动态代理
以租房为例,租客租房,中间经过房屋中介向房东租房,使用代理模式实现
#include
/* 代理模式 */
class RentHouse {
public:
virtual void rentHouse() = 0;
};
class Landlord : public RentHouse {
public:
void rentHouse() {
std::cout << "房子租出去了" << std::endl;
}
};
class Intermediary : public RentHouse {
public:
void rentHouse() {
std::cout << "发布招租启事" << std::endl;
std::cout << "带人看房" << std::endl;
_landload.rentHouse();
std::cout << "负责租后维修" << std::endl;
}
private:
Landlord _landload;
};
int main() {
Intermediary intermediary;
intermediary.rentHouse();
return 0;
}