说依赖抽象变得更加灵活的主要原因在于它提供了更大的替换和扩展的空间。让我们通过一个简单的例子来说明:
考虑一个电商系统,其中有一个OrderProcessor
类负责处理订单,它依赖于一个PaymentGateway
用于处理支付。最初的设计可能如下所示:
public class OrderProcessor {
private PaymentGateway paymentGateway;
public OrderProcessor(PaymentGateway paymentGateway) {
this.paymentGateway = paymentGateway;
}
public void processOrder(Order order) {
// 处理订单逻辑
// ...
// 处理支付
paymentGateway.processPayment(order.getTotalAmount());
}
}
public class PaymentGateway {
public void processPayment(double amount) {
// 处理支付逻辑
}
}
在这个设计中,OrderProcessor
直接依赖于具体的PaymentGateway
实现。这样的设计在初期可能是合理的,但如果未来系统需要支持多种支付方式,这个设计就会显得不够灵活。如果有新的支付方式加入,就需要修改OrderProcessor
的代码,违反了开闭原则。
通过应用依赖倒置原则,我们可以使用抽象来提高灵活性。首先,我们定义一个PaymentProcessor
接口,表示所有支付处理器的抽象:
public interface PaymentProcessor {
void processPayment(double amount);
}
然后,我们修改OrderProcessor
,使其依赖于抽象的PaymentProcessor
:
public class OrderProcessor {
private PaymentProcessor paymentProcessor;
public OrderProcessor(PaymentProcessor paymentProcessor) {
this.paymentProcessor = paymentProcessor;
}
public void processOrder(Order order) {
// 处理订单逻辑
// ...
// 处理支付
paymentProcessor.processPayment(order.getTotalAmount());
}
}
现在,OrderProcessor
不再直接依赖于具体的PaymentGateway
,而是依赖于抽象的PaymentProcessor
接口。这使得我们可以轻松地引入新的支付处理器,而不需要修改OrderProcessor
的代码。例如,我们可以添加一个新的AlipayProcessor
实现:
public class AlipayProcessor implements PaymentProcessor {
@Override
public void processPayment(double amount) {
// Alipay 支付逻辑
}
}
通过这样的设计,我们可以根据需要轻松替换支付处理器,而OrderProcessor
的代码保持不变。这样的设计提供了更大的灵活性和可扩展性,使得系统更容易应对未来的变化。
其实就是保持原来的代码不变的情况下来,处理新的业务逻辑需求。