Skip to content

依赖倒置原则

符合开闭原则:对新增开放,对修改关闭

依赖注入、工厂模式解决手动设置当前用哪一个具体底层实现的不足

依赖注入(Dependency Injection, DI)和工厂模式(Factory Pattern)是实现依赖倒置原则(Dependency Inversion Principle, DIP)的两种常见方式。依赖倒置原则是面向对象设计原则之一,强调高层模块不应依赖于低层模块,二者都应依赖于抽象。下面我们通过 JavaScript 代码示例来说明这两种模式如何帮助实现依赖倒置原则。

依赖注入(Dependency Injection, DI)

依赖注入是一种设计模式,通过将依赖项从外部注入到类中,而不是在类内部直接创建依赖项。这样可以减少类之间的耦合,使得类更加灵活和可测试。

假设我们有一个 UserService,它依赖于 UserRepository 来获取用户数据。我们可以通过依赖注入的方式将 UserRepository 注入到 UserService 中。

js
// UserRepository.js
class UserRepository {
  getUsers() {
    return ['Alice', 'Bob', 'Charlie'];
  }
}

// UserService.js
class UserService {
  constructor(userRepository) {
    this.userRepository = userRepository;
  }

  getAllUsers() {
    return this.userRepository.getUsers();
  }
}

// 使用依赖注入
const userRepository = new UserRepository();
const userService = new UserService(userRepository);

console.log(userService.getAllUsers()); // 输出: ['Alice', 'Bob', 'Charlie']

在这个例子中,UserService 不直接依赖于具体的 UserRepository 实现,而是通过构造函数接收一个 UserRepository 实例。这样,UserService 就可以与任何实现了 UserRepository 接口的类一起工作,符合依赖倒置原则。

工厂模式(Factory Pattern)

工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,而无需指定具体的类。工厂模式可以帮助我们将对象的创建逻辑与使用逻辑分离,从而降低耦合。

假设我们有一个 Logger 接口,并且有多个不同的日志实现(如 ConsoleLogger 和 FileLogger)。我们可以使用工厂模式来创建这些日志实例。

js
// Logger.js
class Logger {
  log(message) {
    throw new Error('Method not implemented');
  }
}

// ConsoleLogger.js
class ConsoleLogger extends Logger {
  log(message) {
    console.log(`Console: ${message}`);
  }
}

// FileLogger.js
class FileLogger extends Logger {
  log(message) {
    // 模拟将日志写入文件
    console.log(`File: ${message}`);
  }
}

// LoggerFactory.js
class LoggerFactory {
  static createLogger(type) {
    switch (type) {
      case 'console':
        return new ConsoleLogger();
      case 'file':
        return new FileLogger();
      default:
        throw new Error('Unknown logger type');
    }
  }
}

// 使用工厂模式
const logger = LoggerFactory.createLogger('console');
logger.log('This is a log message'); // 输出: Console: This is a log message

在这个例子中,LoggerFactory 负责创建具体的 Logger 实例。高层模块(如使用 Logger 的代码)不需要知道具体的 Logger 实现,只需要通过工厂获取 Logger 实例即可。这样,高层模块和低层模块都依赖于 Logger 抽象,符合依赖倒置原则。

苏ICP备2025160170号-1 | 前端进化之路 | Released under the MIT License.