设计模式之依赖注入(DI)

65 篇文章 0 订阅
8 篇文章 0 订阅

一、概念

1. 关注点分离:对象生命周期的管理应该独立于其领域的业务逻辑之外;

2. 依赖注入(DI):将组件与其需要的服务分离,这样组件就不必知道这些服务的名称,也不必知道如何获取它们。

【解释】客户端对象需要的独立的服务对象是由外部提供的。客户端对象不需要关心它所需要的服务对象本身,或者主动请求服务对象。

方式:1. 通过构造函数注入

           2. 通过setter注入

           3. 通过小类大对象中的多态继承的方式注入 

3. 依赖倒置(DIP):解耦技术

4. 单例:类似于全局变量

缺点:1、对单例对象的依赖都藏于代码中,通过类的接口无法知道依赖关系

           2、测试时无法被替身替代,不利于测试

           3、需求的变化,可能导致依赖单例的类都需要被修改

二、实现

不好的实现:单例模式

//单例模式
class Logger final
{
public:
	static Logger& getInstance()
	{
		static Logger& theLogger{};
		return theLogger;
	}

	void writeInfoEntry(std::string_view entry)
	{
		//...
	}

	void writeWarnEntry(std::string_view entry)
	{
		//...
	}

	void writeErrorEntry(std::string_view entry)
	{
		//...
	}
};

// ======================================================
class Customer
{

};

class CustomerRepository
{
public:
	Customer findCustomerById(const int id)
	{
		Logger::getInstance().writeInfoEntry("log.....");
		//...
	}
};

优化:解决强依赖问题,依赖倒置原则

#include <memory>
#include <string_view>
#include <iostream>

//接口
class LoggingFacility
{
public:
	virtual ~LoggingFacility() = default;
	virtual void writeInfoEntry(std::string_view entry) = 0;
	virtual void writeWarnEntry(std::string_view entry) = 0;
	virtual void writeErrorEntry(std::string_view entry) = 0;
};

using Logger = std::shared_ptr<LoggingFacility>;

//实现
class StandardOutputLogger : public LoggingFacility
{
	virtual void writeInfoEntry(std::string_view entry) override
	{
		std::cout << "[INFO] " << entry << std::endl;
	}

	virtual void writeWarnEntry(std::string_view entry) override
	{
		std::cout << "[WARNING] " << entry << std::endl;
	}

	virtual void writeErrorEntry(std::string_view entry) override
	{
		std::cout << "[ERROR] " << entry << std::endl;
	}
};

class Customer
{
	//...
};

class CustomerRepository
{
public:
	CustomerRepository() = delete;
	explicit CustomerRepository(const Logger& loggingService) : logger(loggingService) // 依赖于接口
	{}

	Customer findCustomerById(const int id)
	{
		logger->writeInfoEntry("log.....");
		//...
	}

private:
	Logger logger;
};

UML图

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值