在代码开发的世界里,理论知识的重要性毋庸置疑,但实战经验往往才是知识的真正试金石。正所谓,“读万卷书不如行万里路”,理论的学习需要通过实践来验证和深化。设计模式作为软件开发中的重要理论,其真正的价值在于它们在解决实际问题时的应用。之前的一篇文章中,我们通过物流系统,引入了策略+工厂方法模式,感兴趣的读者可以去阅读Java设计模式实战:从If-Else到策略+工厂方法的演变,本文将再通过支付系统来展示策略模式+观察者模式+命令模式+组合模式的混合模式在实际开发中的应用。
本文不仅是对设计模式的理论讲解,更是一次深入实战的探索。无论你是一名经验丰富的开发者还是刚入行的新手,看一遍肯定记不住,请记得收藏本文,相信一定会为你在未来工作中,引入设计模式提供一份参考
Payment
实体类PaymentSystemService
接口PaymentSystemServiceImpl
实现类简单来说支付系统需要处理多种支付方式,还要与其他系统组件,比如风控、营销等系统进行交互,是比较复杂且难以设计的一类系统。我们就以支付系统为例,引入混合设计模式来优化
在接下来的部分中,我们将探讨如何通过引入策略模式、观察者模式和命令及组合模式的混合模式来解决这些挑战,提高支付系统的灵活性、可扩展性和可维护性
①定义Payment
实体类:
import java.math.BigDecimal;
import java.util.List;
import java.util.ArrayList;
class Payment {
String paymentType;
BigDecimal amount;
Payment(String paymentType, BigDecimal amount) {
this.paymentType = paymentType;
this.amount = amount;
}
}
②定义PaymentSystemService
接口:
import java.util.List;
public interface PaymentSystemService {
void processPayments(List<Payment> payments);
}
③定义PaymentSystemServiceImpl
实现类:
public class PaymentSystemServiceImpl implements PaymentSystemService {
@Override
public void processPayments(List<Payment> payments) {
// 处理支付
processPaymentMethod(payments);
// 支付完成后的通知
notifyRiskManagement(payments);
// 上报埋点日志
logTransactions(payments);
}
private void processPaymentMethod(List<Payment> payments) {
for (Payment payment : payments) {
switch (payment.paymentType) {
case "CreditCard":
System.out.println("Processing credit card payment: " + payment.amount);
break;
case "PayPal":
System.out.println("Processing PayPal payment: " + payment.amount);
break;
// 其他支付方式...
}
}
}
// 通知风控
private void notifyRiskManagement(List<Payment> payments) {
System.out.println("Notifying risk management for payment.");
}
// 日志埋点
private void logTransactions(List<Payment> payments) {
for (Payment payment : payments) {
System.out.println("Logging transaction: Payment type: " +
payment.paymentType + ", Amount: " + payment.amount);
}
}
}
④模拟调用
public class Main {
public static void main(String[] args) {
PaymentSystemService paymentService = new PaymentSystemServiceImpl();
// 示例:组合支付
List<Payment> combinedPayments = new ArrayList<>();
combinedPayments.add(new Payment("CreditCard", new BigDecimal("50.0")));
combinedPayments.add(new Payment("PayPal", new BigDecimal("25.0")));
paymentService.processPayments(combinedPayments);
// 示例:单一支付
// List<Payment> singlePayment = new ArrayList<>();
// singlePayment.add(new Payment("CreditCard", new BigDecimal("75.0")));
// paymentService.processPayments(singlePayment);
}
}
在上述的初始实现中,PaymentSystemServiceImpl
类直接处理了所有的支付逻辑。这种实现方式存在几个主要问题:
PaymentSystemServiceImpl
类耦合,使得该类承担了过多的责任。每种支付方式的逻辑都集中在一个类中,违反了单一职责原则PaymentSystemServiceImpl
类,这违反了开闭原则为了解决这些问题,我们第一时间可以考虑引入策略模式来处理不同支付方式的逻辑,使得每种支付方式都有自己的策略类,解决这个主要问题
策略模式是一种行为设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互换。策略模式让算法的变化独立于使用算法的客户
在支付系统中,我们可以定义一个支付策略接口,每种支付方式实现这个接口。PaymentSystemServiceImpl
类可以使用这些策略来处理不同的支付方式,而不是直接实现所有支付逻辑
①定义策略接口PaymentStrategy
以及具体的策略类CreditCardPaymentStrategy
…:
import java.math.BigDecimal;
/**
* 定义支付策略的接口。
*/
public interface PaymentStrategy {
/**
* 检查此策略是否适用于指定的支付类型。
*
* @param paymentType 支付类型
* @return 如果策略适用于该支付类型,则返回 true
*/
boolean appliesTo(String paymentType);
/**
* 处理支付。
*
* @param amount 支付金额
*/
void processPayment(BigDecimal amount);
}
/**
* 信用卡支付策略。
*/
public class CreditCardPaymentStrategy implements PaymentStrategy {
@Override
public boolean appliesTo(String paymentType) {
return "CreditCard".equals(paymentType);
}
@Override
public void processPayment(BigDecimal amount) {
System.out.println("Processing credit card payment: " + amount);
// 实现信用卡支付逻辑
}
}
/**
* PayPal支付策略。
*/
public class PayPalPaymentStrategy implements PaymentStrategy {
@Override
public boolean appliesTo(String paymentType) {
return "PayPal".equals(paymentType);
}
@Override
public void processPayment(BigDecimal amount) {
System.out.println("Processing PayPal payment: " + amount);
// 实现PayPal支付逻辑
}
}
②修改PaymentSystemServiceImpl
类:
public class PaymentSystemServiceImpl implements PaymentSystemService {
private List<PaymentStrategy> paymentStrategies;
public setPaymentStrategy(List<PaymentStrategy> paymentStrategies) {
this.paymentStrategies = paymentStrategies;
}
@Override
public void processPayments(List<Payment> payments) {
for (Payment payment : payments) {
// 匹配策略
PaymentStrategy strategy = paymentStrategies.stream()
.filter(s -> s.appliesTo(payment.paymentType))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("
No strategy found for payment type: " + payment.paymentType));
strategy.processPayment(payment.amount);
}
// 支付完成后的通知
notifyRiskManagement(payments);
logTransactions(payments);
}
// ... notifyRiskManagement and logTransactions methods ...
}
③模拟调用
public class Main {
public static void main(String[] args) {
// 构造策略
List<PaymentStrategy> strategies = new ArrayList<>();
strategies.add(new CreditCardPaymentStrategy());
strategies.add(new PayPalPaymentStrategy());
// 注入策略
PaymentSystemService paymentService = new PaymentSystemServiceImpl();
paymentService.setPaymentStrategy(stategies);
// 模拟组合支付场景
List<Payment> payments = new ArrayList<>();
payments.add(new Payment("CreditCard", new BigDecimal("50.0")));
payments.add(new Payment("PayPal", new BigDecimal("25.0")));
paymentService.processPayments(payments);
}
}
先看下当前代码的类图结构:
这个类图包括以下部分:
PaymentSystemService
接口,定义了处理支付的方法PaymentSystemServiceImpl
类,实现了 PaymentSystemService
接口,并使用策略模式处理支付PaymentStrategy
接口,定义了支付策略的方法CreditCardPaymentStrategy
和 PayPalPaymentStrategy
类,实现了 PaymentStrategy
接口,分别表示信用卡和PayPal的支付策略存在的问题点:
PaymentSystemService
,显然违背了单一职责PaymentSystemServiceImpl
类的责任,这可能导致策略管理复杂因此我们考虑一个个问题依次解决,先引入观察者模式,以便解耦PaymentSystemServiceImpl
类与通知,通知交给具体的观察者即可。这样可以用于实现更灵活的通知机制,后续可以动态添加或修改观察者
观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。这种模式非常适合实现事件处理系统。
在观察者模式中,存在两类主要角色:
import java.math.BigDecimal;
import java.util.List;
import java.util.ArrayList;
// 观察者接口
interface Observer {
void update(Payment payment);
}
// 主题接口
interface Subject {
// 注册观察者
void registerObserver(Observer o);
// 移除观察者
void removeObserver(Observer o);
// 通知观察者
void notifyObservers(Payment payment);
}
// 支付策略接口
interface PaymentStrategy {
boolean appliesTo(String paymentType);
void processPayment(BigDecimal amount);
}
// 具体的支付策略实现
class CreditCardPaymentStrategy implements PaymentStrategy {
@Override
public boolean appliesTo(String paymentType) {
return "CreditCard".equals(paymentType);
}
@Override
public void processPayment(BigDecimal amount) {
System.out.println("Processing credit card payment: " + amount);
}
}
class PayPalPaymentStrategy implements PaymentStrategy {
@Override
public boolean appliesTo(String paymentType) {
return "PayPal".equals(paymentType);
}
@Override
public void processPayment(BigDecimal amount) {
System.out.println("Processing PayPal payment: " + amount);
}
}
// 支付服务实现类
class PaymentSystemServiceImpl implements PaymentSystemService, Subject {
private List<Observer> observers = new ArrayList<>();
private List<PaymentStrategy> paymentStrategies;
public PaymentSystemServiceImpl(List<PaymentStrategy> paymentStrategies) {
this.paymentStrategies = paymentStrategies;
}
@Override
public void processPayments(List<Payment> payments) {
for (Payment payment : payments) {
PaymentStrategy strategy = paymentStrategies.stream()
.filter(s -> s.appliesTo(payment.paymentType))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No strategy
found for payment type: " + payment.paymentType));
strategy.processPayment(payment.amount);
notifyObservers(payment);
}
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers(Payment payment) {
for (Observer observer : observers) {
observer.update(payment);
}
}
}
// 支付类
class Payment {
String paymentType;
BigDecimal amount;
Payment(String paymentType, BigDecimal amount) {
this.paymentType = paymentType;
this.amount = amount;
}
}
// 风控系统观察者
class RiskManagementObserver implements Observer {
@Override
public void update(Payment payment) {
System.out.println("Risk Management notified for payment: " + payment.amount);
// 实现风控逻辑
notifyRiskManagement(payment);
}
private void notifyRiskManagement(Payment payment) {
// 风控通知逻辑
}
}
// 日志系统观察者
class LoggingObserver implements Observer {
@Override
public void update(Payment payment) {
System.out.println("Logging payment transaction: " + payment.amount);
// 实现日志记录逻辑
logTransaction(payment);
}
private void logTransaction(Payment payment) {
// 日志记录逻辑
}
}
// 主方法
public class Main {
public static void main(String[] args) {
List<PaymentStrategy> strategies = new ArrayList<>();
strategies.add(new CreditCardPaymentStrategy());
strategies.add(new PayPalPaymentStrategy());
PaymentSystemServiceImpl paymentService = new PaymentSystemServiceImpl(strategies);
paymentService.registerObserver(new RiskManagementObserver());
paymentService.registerObserver(new LoggingObserver());
List<Payment> payments = new ArrayList<>();
payments.add(new Payment("CreditCard", new BigDecimal("50.0")));
payments.add(new Payment("PayPal", new BigDecimal("25.0")));
paymentService.processPayments(payments);
}
}
引入观察者模式后的类图:
组合支付的时序流程图:
解耦通知机制:
观察者模式将支付完成后的通知逻辑(如风控通知和日志记录)从 PaymentSystemServiceImpl
类中解耦出来。每个观察者负责处理特定的响应逻辑,降低了主类的复杂性
提高灵活性和可扩展性:
通过观察者模式,可以轻松添加或移除观察者,无需修改主类的代码。这使得在支付系统中引入新的通知类型(如财务记账通知)变得更加简单
更好地遵循单一职责原则:
观察者模式使得每个类(包括主类和观察者)都专注于单一的职责,提高了代码的可维护性
策略管理复杂性:问题依然存在,尽管观察者模式优化了通知机制,但支付策略的管理(如策略的选择和执行)仍然是 PaymentSystemServiceImpl
类的责任,这可能导致策略管理复杂
组合支付处理不足:问题依然存在,当前的实现可能不足以优雅地处理组合支付场景,即在单次交易中使用多种支付方式。这需要更复杂的逻辑来协调不同支付方式的处理
解决策略:
PaymentSystemServiceImpl
类中分离出来,进一步提高系统的灵活性和可维护性import java.math.BigDecimal;
import java.util.List;
import java.util.ArrayList;
// 观察者接口
interface Observer {
void update(BigDecimal amount);
}
// 主题接口
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers(BigDecimal amount);
}
// 命令接口
interface PaymentCommand {
void execute();
}
// 具体的支付命令
class ConcretePaymentCommand implements PaymentCommand {
private PaymentStrategy strategy;
private BigDecimal amount;
private Subject subject;
ConcretePaymentCommand(PaymentStrategy strategy, BigDecimal amount, Subject subject) {
this.strategy = strategy;
this.amount = amount;
this.subject = subject;
}
@Override
public void execute() {
strategy.processPayment(amount);
subject.notifyObservers(amount);
}
}
// 支付策略接口
interface PaymentStrategy {
void processPayment(BigDecimal amount);
}
// 具体的支付策略
class CreditCardPaymentStrategy implements PaymentStrategy {
@Override
public void processPayment(BigDecimal amount) {
System.out.println("Processing credit card payment: " + amount);
}
}
class PayPalPaymentStrategy implements PaymentStrategy {
@Override
public void processPayment(BigDecimal amount) {
System.out.println("Processing PayPal payment: " + amount);
}
}
// 支付组件接口(组合模式)
interface PaymentComponent {
void processPayment();
}
// 单一支付(叶子节点)
class SinglePayment implements PaymentComponent {
private PaymentCommand command;
SinglePayment(PaymentCommand command) {
this.command = command;
}
@Override
public void processPayment() {
command.execute();
}
}
// 组合支付(复合节点)
class CompositePayment implements PaymentComponent {
private List<PaymentComponent> payments = new ArrayList<>();
void addPayment(PaymentComponent payment) {
payments.add(payment);
}
@Override
public void processPayment() {
for (PaymentComponent payment : payments) {
payment.processPayment();
}
}
}
// 支付服务实现(同时作为主题)
class PaymentSystemServiceImpl implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers(BigDecimal amount) {
for (Observer observer : observers) {
observer.update(amount);
}
}
void processPayments(PaymentComponent paymentComponent) {
paymentComponent.processPayment();
}
}
// 观察者实现
class RiskManagementObserver implements Observer {
@Override
public void update(BigDecimal amount) {
System.out.println("Risk Management notified for payment: " + amount);
}
}
class LoggingObserver implements Observer {
@Override
public void update(BigDecimal amount) {
System.out.println("Logging payment transaction: " + amount);
}
}
// 主方法
public class Main {
public static void main(String[] args) {
PaymentSystemServiceImpl paymentService = new PaymentSystemServiceImpl();
paymentService.registerObserver(new RiskManagementObserver());
paymentService.registerObserver(new LoggingObserver());
PaymentStrategy creditCardStrategy = new CreditCardPaymentStrategy();
PaymentStrategy payPalStrategy = new PayPalPaymentStrategy();
SinglePayment creditCardPayment = new SinglePayment(new ConcretePaymentCommand(creditCardStrategy, new BigDecimal("50.0"), paymentService));
SinglePayment payPalPayment = new SinglePayment(new ConcretePaymentCommand(payPalStrategy, new BigDecimal("25.0"), paymentService));
CompositePayment compositePayment = new CompositePayment();
compositePayment.addPayment(creditCardPayment);
compositePayment.addPayment(payPalPayment);
paymentService.processPayments(compositePayment);
}
}
现在完整的类图:
这个类图包括以下部分:
通过这种混合模式设计,支付系统不仅变得更加灵活和可扩展,而且更易于管理和维护。这为应对不断变化的业务需求和技术挑战提供了坚实的基础
比起写代码,写文章确实很难,一方面时间精力有限,一方面难以直接将工作代码放在这里,只能自己去编写示例,难免会有疏漏,可能不是特别准确。但总体相信,一定可以给你带来一些思想上的启发。
通过混合使用策略模式、命令模式、组合模式和观察者模式,成功地构建了一个灵活、可扩展且易于维护的支付系统。这种设计不仅提高了系统的模块化和解耦,还优化了支付处理和通知机制,确保了代码的清晰性和可维护性。这些模式的结合展示了如何有效地应对复杂系统设计中的常见挑战,同时保持代码的整洁性与扩展性
希望这篇文章能够为你提供有价值的见解,并帮助你在未来的项目中应用这些设计模式。
我是程序员三毛,如果您觉得这篇文章对您有帮助,请不吝点赞、关注和收藏。您的支持是我不断前进的动力!