PHP依赖注入:是否应注入依赖注入容器(DIC)?
基于依赖注入的类结构实现示例
我来给你梳理下这个依赖注入风格的类结构实现,把核心框架代码和应用层使用逻辑清晰地展示出来:
框架代码(核心组件)
这部分是基础工具类,负责提供日志、数据库、Redis等基础能力,通过构造函数注入实现组件解耦:
Logger 类(简单日志组件)
负责基础的日志记录功能,是其他组件的核心依赖项:
class Logger { public function log(string $message): void { // 可按需扩展为写入文件、日志服务等实现 echo "Log: {$message}\n"; } }
Database 类(依赖注入 Logger)
数据库操作类,通过构造函数注入Logger来记录初始化、查询等关键操作日志:
class Database { private Logger $log; private string $dbConfig; // 构造函数注入Logger实例与数据库配置参数 public function __construct(Logger $log, string $dbConfig) { $this->log = $log; $this->dbConfig = $dbConfig; $this->log->log("Database initialized with config: {$dbConfig}"); } // 示例:执行SQL并记录操作日志 public function query(string $sql): void { $this->log->log("Executing SQL query: {$sql}"); // 实际的数据库查询逻辑写在这里 } }
Redis 类(依赖注入 Logger)
Redis缓存操作类,同样依赖Logger来记录连接、缓存操作等日志:
class Redis { private Logger $log; private string $redisHost; public function __construct(Logger $log, string $redisHost) { $this->log = $log; $this->redisHost = $redisHost; $this->log->log("Redis client connected to host: {$redisHost}"); } // 示例:设置缓存并记录操作日志 public function set(string $key, mixed $value): void { $this->log->log("Redis set operation for key: {$key}"); // 实际的缓存设置逻辑写在这里 } }
业务逻辑类(注入所有核心组件)
业务层类,通过构造函数注入Logger、Database、Redis所有依赖,专注于业务逻辑实现:
class BusinessLogic { private Logger $log; private Database $db; private Redis $redis; // 一次性注入所有需要的依赖组件 public function __construct(Logger $log, Database $db, Redis $redis) { $this->log = $log; $this->db = $db; $this->redis = $redis; $this->log->log("BusinessLogic component initialized successfully"); } // 示例业务方法:结合缓存与数据库处理用户请求 public function processUserRequest(int $userId): void { $this->log->log("Start processing request for user ID: {$userId}"); // 先尝试从Redis获取缓存数据 $this->redis->set("user_{$userId}", "sample_user_data"); // 再执行数据库查询操作 $this->db->query("SELECT * FROM users WHERE id = {$userId}"); } }
应用代码(业务层使用示例)
这部分是实际业务代码,负责实例化所有组件并组装依赖关系:
// 1. 先实例化最基础的Logger组件 $logger = new Logger(); // 2. 实例化Database和Redis,传入Logger实例作为依赖 $database = new Database($logger, "mysql:host=localhost;dbname=my_app"); $redisClient = new Redis($logger, "localhost:6379"); // 3. 实例化业务逻辑类,注入所有依赖组件 $businessService = new BusinessLogic($logger, $database, $redisClient); // 4. 调用业务方法处理请求 $businessService->processUserRequest(456);
这种依赖注入方式的优势
- 职责单一:每个类只负责自己的核心功能,Logger管日志,Database管数据库,业务类管业务逻辑
- 易于测试:测试时可以轻松替换Logger为Mock对象,不用修改核心业务代码
- 组件解耦:后续如果要更换数据库驱动或缓存服务,只需要修改对应组件类,不影响业务逻辑
内容的提问来源于stack exchange,提问作者779IDEAS
相关产品推荐
相关产品推荐

