类的职责应该单⼀,⼀个⽅法只做⼀件事,职责划分清晰了
对扩展开放,对修改封闭对软件实体的改动,最好⽤扩展⽽⾮修改的⽅式。
通俗点讲,就是只要⽗类能出现的地⽅,⼦类就可以出现,⽽且替换为⼦类也不会产⽣任何错误或异常。在继承类时,务必重写⽗类中所有的⽅法,尤其需要注意⽗类的protected⽅法,⼦类尽量不要暴露⾃⼰的public⽅法供外界调⽤。
⾼层模块不应该依赖低层模块,两者都应该依赖其抽象. 不可分割的原⼦逻辑就是低层模式,原⼦逻辑组装成的就是⾼层模块。模块间依赖通过抽象(接⼝)发⽣,具体类之间不直接依赖
尽量减少对象之间的交互,从⽽减⼩类之间的耦合。⼀个对象应该对其他对象有最少的了解。
客⼾端不应该依赖它不需要的接⼝,类间的依赖关系应该建⽴在最⼩的接⼝上使⽤建议:接⼝设计尽量精简单⼀,但是不要对外暴露没有实际意义的接⼝。⽤例:修改密码,不应该提供修改⽤⼾信息接⼝,⽽就是单⼀的最⼩修改密码接⼝,更不要暴露数据库操作
从整体上来理解六⼤设计原则,可以简要的概括为⼀句话,⽤抽象构建框架,⽤实现扩展细节,具体 到每⼀条设计原则,则对应⼀条注意事项:
单⼀职责原则告诉我们实现类要职责单⼀;⾥⽒替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要⾯向接⼝编程;接⼝隔离原则告诉我们在设计接⼝的时候要精简单⼀;迪⽶特法则告诉我们要降低耦合;开闭原则是总纲,告诉我们要对扩展开放,对修改关闭。
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个
访问它的全局访问点,该实例被所有程序模块共享。
比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
单例模式有两种实现模式:饿汉模式,懒汉模式
就是说不管你将来用不用,程序启动时就会创建⼀个唯⼀的实例对象。 因为单例对象已经确定, 所以⽐较适⽤于多线程环境中, 多线程获取单例对象不需要加锁, 可以有效的避免资源竞争, 提⾼性能。
- #include
- using namespace std;
-
- class Singleton {
- private:
- static Singleton _eton;
- int _data;
- private:
- Singleton() :_data(99) {
- cout << "单例对象构造" << endl;
- }
- ~Singleton() {}
- public:
- Singleton(const Singleton&) = delete;
- Singleton& operator=(const Singleton&) = delete;
- static Singleton& getInstance()
- {
- return _eton;
- }
- int getData() {
- return _data;
- }
- };
- Singleton Singleton::_eton;
-
-
- int main()
- {
- //cout << Singleton::getInstance().getData() << endl;
- return 0;
- }
结果演示
注释前:

注释后:

由此可见,在main函数启动后,就会自动构造单例对象,即便是没有调用该单例对象。
第⼀次使⽤要使⽤单例对象的时候创建实例对象。如果单例对象构造特别耗时或者耗费资源(加载插件、加载⽹络资源等), 可以选择懒汉模式, 在第⼀次使⽤的时候才创建对象。
- class B
- {
- public:
- static B* GetInstance()
- {
- if (_inst == nullptr)
- {
- _inst = new B;
- }
-
- return _inst;
- }
-
- static void DelInstance()
- {
- if (_inst)
- {
- delete _inst;
- _inst = nullptr;
- }
- }
-
- private:
- B()
- {}
-
- ~B()
- {
- cout << "数据写到文件" << endl;
- }
-
- B(const B& aa) = delete;
- B& operator=(const B& aa) = delete;
-
- static B* _inst;
-
- class gc
- {
- public:
- ~gc()
- {
- DelInstance();
- }
- };
-
- static gc _gc;
- };
-
- B* B::_inst = nullptr;
- B::gc B::_gc;
下面再介绍一种《Effective C++》⼀书作者 Scott Meyers 提出的⼀种更加优雅简便的单例模式 Meyers' Singleton in C++。
C++11 Static local variables 特性以确保C++11起,静态变量将能够在满⾜ thread-safe 的前提下唯⼀地被构造和析构。
- #include
- using namespace std;
-
- class Singleton {
- private:
- int _data;
- private:
- Singleton() :_data(99) {
- cout << "单例对象构造" << endl;
- }
- ~Singleton() {}
- public:
- Singleton(const Singleton&) = delete;
- Singleton& operator=(const Singleton&) = delete;
- static Singleton& getInstance()
- {
- static Singleton _eton;
- return _eton;
- }
- int getData() {
- return _data;
- }
- };
-
-
- int main()
- {
- cout << Singleton::getInstance().getData() << endl;
- return 0;
- }
结果演示
没注释:

注释后:

由此可见,懒汉模式中,只有第一次创建对象时,才会构造单例对象。
简单⼯⼚模式:通过参数控制可以⽣产任何产品
优点:简单粗暴,直观易懂。使⽤⼀个⼯⼚⽣产同⼀等级结构下的任意产品
缺点:
1. 所有东西⽣产在⼀起,产品太多会导致代码量庞⼤
2. 开闭原则遵循(开放拓展,关闭修改)的不是太好,要新增产品就必须修改⼯⼚⽅法。
- #include
- #include
- #include
- class Fruit {
- public:
- Fruit() {}
- virtual void show() = 0;
- };
- class Apple : public Fruit {
- public:
- Apple() {}
- virtual void show() {
- std::cout << "我是一个苹果" << std::endl;
- }
- };
- class Banana : public Fruit {
- public:
- Banana() {}
- virtual void show() {
- std::cout << "我是一个香蕉" << std::endl;
- }
- };
- class FruitFactory {
- public:
- static std::shared_ptr
create(const std::string& name) { - if (name == "苹果") {
- return std::make_shared
(); - }
- else if (name == "⾹蕉") {
- return std::make_shared
(); - }
- return std::shared_ptr
(); - }
- };
- int main()
- {
- std::shared_ptr
fruit = FruitFactory::create("苹果"); - fruit->show();
- fruit = FruitFactory::create("⾹蕉");
- fruit->show();
- return 0;
- }
⼯⼚⽅法:定义⼀个创建对象的接⼝,但是由⼦类来决定创建哪种对象,使⽤多个⼯⼚分别⽣产指定的固定产品
优点:
1. 减轻了⼯⼚类的负担,将某类产品的⽣产交给指定的⼯⼚来进⾏
2. 开闭原则遵循较好,添加新产品只需要新增产品的⼯⼚即可,不需要修改原先的⼯⼚类
缺点:对于某种可以形成⼀组产品族的情况处理较为复杂,需要创建⼤量的⼯⼚类.
- #include
- #include
- #include
-
-
- class Fruit {
- public:
- Fruit() {}
- virtual void show() = 0;
- };
- class Apple : public Fruit {
- public:
- Apple() {}
- virtual void show() {
- std::cout << "我是一个苹果" << std::endl;
- }
- private:
- std::string _color;
- };
- class Banana : public Fruit {
- public:
- Banana() {}
- virtual void show() {
- std::cout << "我是一个香蕉" << std::endl;
- }
- };
- class FruitFactory {
- public:
- virtual std::shared_ptr
create() = 0; - };
- class AppleFactory : public FruitFactory {
- public:
- virtual std::shared_ptr
create() { - return std::make_shared
(); - }
- };
- class BananaFactory : public FruitFactory {
- public:
- virtual std::shared_ptr
create() { - return std::make_shared
(); - }
- };
- int main()
- {
- std::shared_ptr
factory(new AppleFactory()) ; - std::shared_ptr
fruit = factory->create(); - fruit->show();
- factory.reset(new BananaFactory());
- fruit = factory->create();
- fruit->show();
- return 0;
- }
运行结果:

抽象⼯⼚:围绕⼀个超级⼯⼚创建其他⼯⼚。每个⽣成的⼯⼚按照⼯⼚模式提供对象。
思想:将⼯⼚抽象成两层,抽象⼯⼚ & 具体⼯⼚⼦类, 在⼯⼚⼦类种⽣产不同类型的⼦产品
- #include
- #include
- #include
-
- class Fruit {
- public:
- Fruit() {}
- virtual void show() = 0;
- };
- class Apple : public Fruit {
- public:
- Apple() {}
- virtual void show() {
- std::cout << "我是一个苹果" << std::endl;
- }
- private:
- std::string _color;
- };
- class Banana : public Fruit {
- public:
- Banana() {}
- virtual void show() {
- std::cout << "我是一个香蕉" << std::endl;
- }
- };
- class Animal {
- public:
- virtual void voice() = 0;
- };
- class Lamp : public Animal {
- public:
- void voice() { std::cout << "咩咩咩\n"; }
- };
- class Dog : public Animal {
- public:
- void voice() { std::cout << "汪汪汪\n"; }
- };
- class Factory {
- public:
- virtual std::shared_ptr
getFruit(const std::string& name) = 0; - virtual std::shared_ptr
getAnimal(const std::string& name) = 0; - };
- class FruitFactory : public Factory {
- public:
- virtual std::shared_ptr
getAnimal(const std::string& name) { - return std::shared_ptr
(); - }
- virtual std::shared_ptr
getFruit(const std::string& name) { - if (name == "苹果") {
- return std::make_shared
(); - }
- else if (name == "⾹蕉") {
- return std::make_shared
(); - }
- return std::shared_ptr
(); - }
- };
- class AnimalFactory : public Factory {
-
- public:
- virtual std::shared_ptr
getFruit(const std::string& name) { - return std::shared_ptr
(); - }
- virtual std::shared_ptr
getAnimal(const std::string& name) { - if (name == "⼩⽺") {
- return std::make_shared
(); - }
- else if (name == "⼩狗") {
- return std::make_shared
(); - }
- return std::shared_ptr
(); - }
- };
- class FactoryProducer {
- public:
- static std::shared_ptr
getFactory(const std::string& name) { - if (name == "动物") {
- return std::make_shared
(); - }
- else {
- return std::make_shared
(); - }
- }
- };
- int main()
- {
- std::shared_ptr
fruit_factory = FactoryProducer::getFactory("⽔果"); - std::shared_ptr
fruit = fruit_factory->getFruit("苹果"); - fruit->show();
- fruit = fruit_factory->getFruit("⾹蕉");
- fruit->show();
- std::shared_ptr
animal_factory = FactoryProducer::getFactory("动物"); - std::shared_ptr
animal = animal_factory->getAnimal("⼩⽺"); - animal->voice();
- animal = animal_factory->getAnimal("⼩狗");
- animal->voice();
- return 0;
- }
运行结果:

抽象产品类:
具体产品类:⼀个具体的产品对象类抽象Builder类:创建⼀个产品对象所需的各个部件的抽象接⼝具体产品的Builder类:实现抽象接⼝,构建各个部件指挥者Director类:统⼀组建过程,提供给调⽤者使⽤,通过指挥者来构造产品
- #include
- #include
- /*抽象电脑类*/
- class Computer {
- public:
- Computer() {}
- void setBoard(const std::string& board) { _board = board; }
- void setDisplay(const std::string& display) { _display = display; }
- virtual void setOs() = 0;
- std::string toString() {
- std::string computer = "Computer:{\n";
- computer += "\tboard=" + _board + ",\n";
- computer += "\tdisplay=" + _display + ",\n";
- computer += "\tOs=" + _os + ",\n";
- computer += "}\n";
- return computer;
- }
- protected:
- std::string _board;
- std::string _display;
- std::string _os;
- };
- /*具体产品类*/
- class MacBook : public Computer {
- public:
- MacBook() {}
- virtual void setOs() {
- _os = "Max 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
build() = 0; - };
- /*具体产品的具体建造者类:实现抽象接⼝,构建和组装各个部件*/
- class MacBookBuilder : public Builder {
- public:
- MacBookBuilder() : _computer(new MacBook()) {}
- virtual void buildBoard(const std::string& board) {
- _computer->setBoard(board);
- }
- virtual void buildDisplay(const std::string& display) {
- _computer->setDisplay(display);
- }
- virtual void buildOs() {
- _computer->setOs();
- }
- virtual std::shared_ptr
build() { - return _computer;
- }
- private:
- std::shared_ptr
_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; - };
- int main()
- {
- Builder* buidler = new MacBookBuilder();
- std::unique_ptr
pd(new Director(buidler)) ; - pd->construct("英特尔主板", "VOC显示器");
- std::shared_ptr
computer = buidler->build(); - std::cout << computer->toString();
- return 0;
- }
运行结果:

静态代理指的是,在编译时就已经确定好了代理类和被代理类的关系。也就是说,在编译时就已经确定了代理类要代理的是哪个被代理类。动态代理指的是,在运⾏时才动态⽣成代理类,并将其与被代理类绑定。这意味着,在运⾏时才能确定代理类要代理的是哪个被代理类。
- /*房东要把⼀个房⼦通过中介租出去理解代理模式*/
- #include
- #include
- class RentHouse {
- public:
- virtual void rentHouse() = 0;
- };
- /*房东类:将房⼦租出去*/
- class Landlord : public RentHouse {
- public:
- void rentHouse() {
- std::cout << "将房子租出去\n";
- }
- };
- /*中介代理类:对租房⼦进⾏功能加强,实现租房以外的其他功能*/
- class Intermediary : public RentHouse {
- public:
- void rentHouse() {
- std::cout << "发布招租启示\n";
- std::cout << "带人看房\n";
- _landlord.rentHouse();
- std::cout << "负责租后维修\n";
- }
- private:
- Landlord _landlord;
- };
- int main()
- {
- Intermediary intermediary;
- intermediary.rentHouse();
- return 0;
- }
运行结果:
