常用设计模式

单例模式

一个类只能创建一个对象,即单例模式,该设计模式可以保证系统中该类只有⼀个实例,并提供⼀个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在⼀个文件中,这些配置数据由⼀个单例对象统⼀读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种⽅式简化了在复杂环境下的配置管理。
单例模式有两种实现模式:饿汉模式和懒汉模式

  • 饿汉模式:程序启动时就会创建一个唯一的实例对象。因为单例对象已经确定,所以比较适用于多线程环境中,多线程获取单例对象不需要加锁,可以有效的避免资源竞争,提高性能
  • 懒汉模式:第一次使用要使用单例对象的时候创建实例对象。如果单例对象构造特别耗时或者耗费济源(加载插件、加载网络资源等),可以选择懒汉模式,在第一次使用的时候才创建对象。
#include <iostream>

class Singleton {
    private:
        static Singleton _eton;
        Singleton():_data(99){
            std::cout<<"单例对象构造!\n";
        }
        Singleton(const Singleton&) = delete;
        ~Singleton(){}
    private:
      int _data;
    public:
        static Singleton &getInstance() {
            return _eton;
        }
      int getData(){return _data;}
};
Singleton Singleton::_eton;//饿汉方式的单例
int main() {
    std::cout<<Singleton::getInstance().getData()<<std::endl;
    return 0;
}

工厂模式

工厂模式是⼀种创建型设计模式,它提供了⼀种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对上层暴露创建逻辑,而是通过使用一个共同结构来指向新创建的对象,以此实现创建-使用的分离。
工厂模式可以分为:简单工厂模式和抽象工厂模式

简单工厂模式

简单工厂模式实现由一个工厂对象通过类型决定创建出来指定产品类的实例。假设有个工厂能生产出水果,当客户需要产品的时候明确告知工厂生产哪类水果,工厂需要接用户提供的类别信息,当新增产品的时候,工厂内部去添加新产品的生产方式。

//简单⼯⼚模式:通过参数控制可以⽣产任何产品
// 优点:简单粗暴,直观易懂。使⽤⼀个⼯⼚⽣产同⼀等级结构下的任意产品
// 缺点:
// 1. 所有东西⽣产在⼀起,产品太多会导致代码量庞⼤
// 2. 开闭原则遵循(开放拓展,关闭修改)的不是太好,要新增产品就必须修改⼯⼚⽅法。
#include <iostream>
#include <string>
#include <memory>
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<Fruit> create(const std::string& name) {
		if (name == "苹果") {
			return std::make_shared<Apple>();
		}
		else if (name == "⾹蕉") {
			return std::make_shared<Banana>();
		}
		return std::shared_ptr<Fruit>();
	}
};
int main()
{
	std::shared_ptr<Fruit> fruit = FruitFactory::create("苹果");
	fruit->show();
	fruit = FruitFactory::create("⾹蕉");
	fruit->show();
	return 0;
}

这个模式的结构和管理产品对象的方式十分简单,但是它的扩展性非常差,当我们需要新增产品的时候,就需要去修改工厂类新增⼀个类型的产品创建逻辑,违背了开闭原则。

  • 工厂方法模式:在简单工厂模式下新增多个工厂,多个产品,每个产品对应⼀个工厂。
#include <iostream>
#include <string>
#include <memory>
//⼯⼚⽅法:定义⼀个创建对象的接⼝,但是由⼦类来决定创建哪种对象,使⽤多个⼯⼚分别⽣产指定的固定产品
// 优点:
// 1. 减轻了⼯⼚类的负担,将某类产品的⽣产交给指定的⼯⼚来进⾏
// 2. 开闭原则遵循较好,添加新产品只需要新增产品的⼯⼚即可,不需要修改原先的⼯⼚类
// 缺点:对于某种可以形成⼀组产品族的情况处理较为复杂,需要创建⼤量的⼯⼚类.
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<Fruit> create() = 0;
};
class AppleFactory : public FruitFactory {
public:
	virtual std::shared_ptr<Fruit> create() {
		return std::make_shared<Apple>();
	}
};
class BananaFactory : public FruitFactory {
public:
	virtual std::shared_ptr<Fruit> create() {
		return std::make_shared<Banana>();
	}
};
int main()
{
	std::shared_ptr<FruitFactory> factory(new AppleFactory());
	fruit = factory->create();
	fruit->show();
	factory.reset(new BananaFactory());
	fruit = factory->create();
	fruit->show();
	return 0;
}

抽象工厂模式

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

建造者模式

建造者模式是⼀种创建型设计模式,使用多个简单的对象一步一步构建成一个复杂的对象,能够将一个复杂的对象的构建与它的表示分离,提供一种创建对象的最佳方式。主要用于解决对象的构建过于复杂的问题。
建造者模式主要基于四个核心类实现:

  • 抽象产品类:
  • 具体产品类:⼀个具体的产品对象类
  • 抽象Builder类:创建⼀个产品对象所需的各个部件的抽象接口
  • 具体产品的Builder类:实现抽象接口,构建各个部件
  • 指挥者Director类:统⼀组建过程,提供给调用者使用,通过指挥者来构造产品
#include <iostream>
#include <memory>
/*抽象电脑类*/
class Computer {
public:
	using ptr = std::shared_ptr<Computer>;
	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:
	using ptr = std::shared_ptr<MacBook>;
	MacBook() {}
	virtual void setOs() {
		_os = "Max Os X12";
	}
};
/*抽象建造者类:包含创建⼀个产品对象的各个部件的抽象接⼝*/
class Builder {
public:
	using ptr = std::shared_ptr<Builder>;
	virtual void buildBoard(const std::string& board) = 0;
	virtual void buildDisplay(const std::string& display) = 0;
	virtual void buildOs() = 0;
	virtual Computer::ptr build() = 0;
};
/*具体产品的具体建造者类:实现抽象接⼝,构建和组装各个部件*/
class MacBookBuilder : public Builder {
public:
	using ptr = std::shared_ptr<MacBookBuilder>;
	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 Computer::ptr build() {
		return _computer;
	}
private:
	Computer::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:
	Builder::ptr _builder;
};
int main()
{
	Builder* buidler = new MackBookBuilder();
	std::unique_ptr<Director> pd(new Director(buidler));
	pd->construct("英特尔主板", "VOC显⽰器");
	Computer::ptr computer = buidler->build();
	std::cout << computer->toString();
	return 0;
}

代理模式

代理模式指代理控制对其他对象的访问,也就是代理对象控制对原对象的引用。在某些情况下,一个对象不适合或者不能直接被引用访问,⽽代理对象可以在客户端和目标对象之间起到中介的作用。

/*房东要把⼀个房⼦通过中介租出去理解代理模式*/
#include <iostream>
#include <string>
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;
}
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷帅且洋仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值