深入理解依赖倒置原则
依赖倒置原则不仅仅是关于接口和实现的分离,它更是一种架构设计哲学,主要包括:
- 控制反转:依赖关系的控制权从高层模块转移到外部容器
- 抽象稳定性:抽象比具体实现更稳定,基于抽象的设计更能适应变化
- 框架设计:DIP是许多现代框架(如Spring)的核心理论基础
Java示例
违反DIP的示例
java
// 低层模块 - 具体实现
class EmailService {
public void sendEmail(String message) {
System.out.println("发送邮件: " + message);
}
}
class SMSService {
public void sendSMS(String message) {
System.out.println("发送短信: " + message);
}
}
// 高层模块 - 直接依赖具体实现
class Notification {
private EmailService emailService;
private SMSService smsService;
public Notification() {
this.emailService = new EmailService(); // 紧耦合
this.smsService = new SMSService(); // 紧耦合
}
public void notifyByEmail(String message) {
emailService.sendEmail(message);
}
public void notifyBySMS(String message) {
smsService.sendSMS(message);
}
}
问题分析:
Notification
类直接依赖于具体实现- 难以测试(无法mock依赖)
- 添加新通知方式需要修改
Notification
类
遵循DIP的示例
java
// 步骤1: 定义抽象层
interface MessageService {
void sendMessage(String message);
}
// 步骤2: 具体实现依赖于抽象
class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("发送邮件: " + message);
}
}
class SMSService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("发送短信: " + message);
}
}
class WeChatService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("发送微信: " + message);
}
}
// 步骤3: 高层模块依赖于抽象
class Notification {
private MessageService messageService;
// 通过构造器注入依赖
public Notification(MessageService messageService) {
this.messageService = messageService;
}
public void notifyUser(String message) {
messageService.sendMessage(message);
}
// 通过setter注入依赖
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}
}
使用示例
java
public class DIPDemo {
public static void main(String[] args) {
// 创建具体服务
MessageService emailService = new EmailService();
MessageService smsService = new SMSService();
MessageService wechatService = new WeChatService();
// 通过依赖注入使用不同的服务
Notification emailNotification = new Notification(emailService);
emailNotification.notifyUser("这是一封重要邮件");
Notification smsNotification = new Notification(smsService);
smsNotification.notifyUser("这是一条紧急短信");
// 动态切换服务
Notification notification = new Notification(emailService);
notification.notifyUser("第一条消息通过邮件发送");
notification.setMessageService(wechatService);
notification.notifyUser("第二条消息通过微信发送");
}
}
更复杂的示例 - 订单处理系统
java
// 抽象层
interface PaymentProcessor {
boolean processPayment(double amount);
}
interface OrderRepository {
void save(Order order);
}
interface NotificationService {
void sendOrderConfirmation(Order order);
}
// 具体实现
class CreditCardProcessor implements PaymentProcessor {
@Override
public boolean processPayment(double amount) {
System.out.println("信用卡支付: $" + amount);
return true;
}
}
class PayPalProcessor implements PaymentProcessor {
@Override
public boolean processPayment(double amount) {
System.out.println("PayPal支付: $" + amount);
return true;
}
}
class DatabaseOrderRepository implements OrderRepository {
@Override
public void save(Order order) {
System.out.println("订单保存到数据库: " + order.getId());
}
}
class EmailNotificationService implements NotificationService {
@Override
public void sendOrderConfirmation(Order order) {
System.out.println("发送订单确认邮件: " + order.getId());
}
}
// 订单类
class Order {
private String id;
private double amount;
public Order(String id, double amount) {
this.id = id;
this.amount = amount;
}
// getters...
public String getId() { return id; }
public double getAmount() { return amount; }
}
// 高层模块 - 订单服务
class OrderService {
private PaymentProcessor paymentProcessor;
private OrderRepository orderRepository;
private NotificationService notificationService;
// 依赖注入
public OrderService(PaymentProcessor paymentProcessor,
OrderRepository orderRepository,
NotificationService notificationService) {
this.paymentProcessor = paymentProcessor;
this.orderRepository = orderRepository;
this.notificationService = notificationService;
}
public boolean processOrder(Order order) {
// 处理支付
boolean paymentSuccess = paymentProcessor.processPayment(order.getAmount());
if (!paymentSuccess) {
return false;
}
// 保存订单
orderRepository.save(order);
// 发送通知
notificationService.sendOrderConfirmation(order);
return true;
}
}
// 使用示例
public class OrderSystemDemo {
public static void main(String[] args) {
// 创建依赖
PaymentProcessor paymentProcessor = new PayPalProcessor();
OrderRepository orderRepository = new DatabaseOrderRepository();
NotificationService notificationService = new EmailNotificationService();
// 注入依赖
OrderService orderService = new OrderService(
paymentProcessor, orderRepository, notificationService
);
// 处理订单
Order order = new Order("ORDER123", 99.99);
boolean success = orderService.processOrder(order);
System.out.println("订单处理" + (success ? "成功" : "失败"));
}
}
高级使用
依赖注入容器模拟
java
// 简单的依赖注入容器
class DIContainer {
private final Map<Class<?>, Object> instances = new ConcurrentHashMap<>();
private final Map<Class<?>, Class<?>> implementations = new ConcurrentHashMap<>();
public <T> void register(Class<T> interfaceType, Class<? extends T> implementation) {
implementations.put(interfaceType, implementation);
}
public <T> void registerInstance(Class<T> interfaceType, T instance) {
instances.put(interfaceType, instance);
}
@SuppressWarnings("unchecked")
public <T> T resolve(Class<T> interfaceType) {
// 首先检查是否有现有实例
T instance = (T) instances.get(interfaceType);
if (instance != null) {
return instance;
}
// 创建新实例
Class<?> implementation = implementations.get(interfaceType);
if (implementation == null) {
throw new RuntimeException("No implementation registered for: " + interfaceType);
}
try {
instance = (T) implementation.getDeclaredConstructor().newInstance();
instances.put(interfaceType, instance);
return instance;
} catch (Exception e) {
throw new RuntimeException("Failed to create instance of: " + implementation, e);
}
}
}
// 使用依赖注入容器
class DIPWithContainerDemo {
public static void main(String[] args) {
DIContainer container = new DIContainer();
// 注册依赖
container.register(MessageSender.class, EmailSender.class);
container.register(MessageFilter.class, SensitiveWordFilter.class);
container.register(SendStatusListener.class, LoggingStatusListener.class);
// 解析使用
MessageSender sender = container.resolve(MessageSender.class);
MessageFilter filter = container.resolve(MessageFilter.class);
System.out.println("通过DI容器解析的实例: " + sender.getClass().getSimpleName());
}
}
配置化系统
java
// 基于配置的发送器工厂
class MessageSenderFactory {
private final Properties config;
public MessageSenderFactory(Properties config) {
this.config = config;
}
public List<MessageSender> createSenders() {
List<MessageSender> senders = new ArrayList<>();
if ("true".equals(config.getProperty("email.enabled"))) {
senders.add(new EmailSender(
config.getProperty("email.smtp.server"),
config.getProperty("email.username"),
config.getProperty("email.password")
));
}
if ("true".equals(config.getProperty("sms.enabled"))) {
senders.add(new SMSSender(
config.getProperty("sms.api.key"),
config.getProperty("sms.api.secret")
));
}
// 可以继续添加其他发送器...
return senders;
}
}
优点
- 完全解耦 :高层模块
MessageDispatcher
不依赖任何具体实现 - 易于测试:所有依赖都可以被mock
- 运行时扩展:可以动态添加新的发送器、过滤器、监听器
- 配置灵活:通过配置决定使用哪些组件
- 便于扩展:新功能可以通过实现接口轻松添加