使用 Function 来编写策略模式:优雅而高效的计划模式实践
弁言:为什么选择策略模式?策略模式(Strategy Pattern)是举动计划模式中的经典之一,它答应我们定义一系列的算法或操作,并使得它们可以互换使用。策略模式的关键头脑是将算法的实现与使用它们的上下文分离,使得同一操作可以根据不同的策略来实现。
但在 Java 中,如何实现这个计划模式呢?通常我们会使用接口、抽象类和具体实现来完成,但这往往导致代码复杂、冗长。那么,如何使用 Java 8 引入的 Function 来使策略模式变得更加简便和优雅呢?
这篇文章将展示如何通过 Function 来实现策略模式,从而使得策略模式更加灵活、简便且易于维护。
一、策略模式的传统实现
起首,让我们看看传统的策略模式是如何实现的。在这个例子中,我们有一个 PaymentStrategy,它有多种不同的支付方式,比方 光荣卡支付 和 PayPal 支付。
1. 定义策略接口:
interface PaymentStrategy {
void pay(double amount);
}
2. 实现具体策略:
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);
}
}
class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " using PayPal account: " + email);
}
}
3. 策略上下文:
class PaymentContext {
private PaymentStrategy strategy;
public PaymentContext(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePayment(double amount) {
strategy.pay(amount);
}
}
4. 客户端代码:
public class Main {
public static void main(String[] args) {
PaymentStrategy creditCardPayment = new CreditCardPayment("1234-5678-9876");
PaymentStrategy payPalPayment = new PayPalPayment("user@example.com");
PaymentContext context = new PaymentContext(creditCardPayment);
context.executePayment(100.00);
context = new PaymentContext(payPalPayment);
context.executePayment(200.00);
}
}
通过这种方式,我们使用不同的策略来支付不同的金额。代码看起来清楚,但我们有许多重复的代码结构,如 PaymentStrategy 接口和各个策略类的实现。接下来,我们将使用 Function 来改进这一计划。
二、使用 Function 改进策略模式
在 Java 8 引入的 Function 可以帮助我们简化这个过程。Function 是一个函数式接口,它继承一个输入并返回一个结果。在策略模式中,我们将 Function 作为策略的实现来代替原本的类结构。
1. 使用 Function 定义策略:
我们不再必要定义一个接口或多个类来实现不同的策略,而是直接使用 Function 来表示每种策略。每个 Function 接收一个 double 类型的支付金额并执行支付操作。
2. 改进的策略代码:
import java.util.function.Function;
public class PaymentStrategy {
// 使用 Function 来表示支付策略
public static Function<Double, Void> creditCardPayment(String cardNumber) {
return amount -> {
System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);
return null; // 返回类型为 Void,表示没有返回值
};
}
public static Function<Double, Void> payPalPayment(String email) {
return amount -> {
System.out.println("Paid " + amount + " using PayPal account: " + email);
return null;
};
}
}
3. 策略上下文(更简化):
class PaymentContext {
private Function<Double, Void> strategy;
public PaymentContext(Function<Double, Void> strategy) {
this.strategy = strategy;
}
public void executePayment(double amount) {
strategy.apply(amount);// 使用 Function 的 apply 方法执行支付
}
}
4. 客户端代码:
public class Main {
public static void main(String[] args) {
// 使用 Function 传递支付策略
Function<Double, Void> creditCardPayment = PaymentStrategy.creditCardPayment("1234-5678-9876");
Function<Double, Void> payPalPayment = PaymentStrategy.payPalPayment("user@example.com");
PaymentContext context = new PaymentContext(creditCardPayment);
context.executePayment(100.00);
context = new PaymentContext(payPalPayment);
context.executePayment(200.00);
}
}
三、上风分析:
[*] 简便的代码:
[*]使用 Function 来代替传统的接口和具体类,不仅淘汰了类的数目,而且让代码更加简便。我们不必要为每个策略创建一个类,所有策略的实现都可以在一个地方会合定义。
[*] 灵活性:
[*]Function 可以非常轻易地通过 Lambda 表达式来定义,也可以根据需求动态调整策略。而且,Function 是一个高度可组合的接口,可以通过链式调用来组合多个函数。
[*] 代码维护:
[*]使用 Function 来表达策略使得每个策略变得更加简便且独立,开辟者可以轻松地替换策略或修改策略的举动,而无需修改复杂的类结构。
[*] 与 Java 8+ 特性结合:
[*]结合 Java 8 的 Lambda 表达式、Stream API 等特性,Function 让代码更加符合现代 Java 编程风格。
四、进一步优化:策略的复用和组合
一个重要的应用场景是我们可以通过组合多个 Function 来复用现有策略或创建新策略。比方,我们可以组合支付策略和折扣策略来构建更复杂的支付流程。
示例:组合策略
假设我们必要为支付金额应用折扣:
public class DiscountedPayment {
public static Function<Double, Double> applyDiscount(double discountRate) {
return amount -> amount - (amount * discountRate);
}
public static Function<Double, Void> creditCardPaymentWithDiscount(String cardNumber, double discountRate) {
Function<Double, Double> discount = applyDiscount(discountRate);
return amount -> {
double discountedAmount = discount.apply(amount);
System.out.println("Paid " + discountedAmount + " using Credit Card: " + cardNumber);
return null;
};
}
}
我们可以将折扣策略与支付策略组合:
Function<Double, Void> creditCardPaymentWithDiscount = DiscountedPayment.creditCardPaymentWithDiscount("1234-5678-9876", 0.1);
PaymentContext context = new PaymentContext(creditCardPaymentWithDiscount);
context.executePayment(100.00);// 输出:Paid 90.0 using Credit Card: 1234-5678-9876
五、总结:优雅而高效的策略模式
通过 Function,我们不仅让策略模式更加简便,而且增强了代码的灵活性和可维护性。借助 Lambda 表达式,Java 8+ 中的函数式编程特性,我们能够以一种更现代、更优雅的方式实现策略模式。
本篇要点回顾:
[*]使用 Function 替换传统的策略接口与具体实现类,简化了策略模式的实现。
[*]Function 的高度灵活性和组合能力使得策略模式更加可扩展。
[*]结合 Java 8+ 的特性,策略模式变得更加优雅、高效,淘汰了代码冗余。
你可以实验在本身的项目中应用这个技巧,提拔代码的简便性和可维护性。
保举阅读文章
[*] 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)
[*] 如何明确 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的接洽
[*] HTTP、HTTPS、Cookie 和 Session 之间的关系
[*] 什么是 Cookie?简单介绍与使用方法
[*] 什么是 Session?如何应用?
[*] 使用 Spring 框架构建 MVC 应用程序:初学者教程
[*] 有缺陷的 Java 代码:Java 开辟人员最常犯的 10 大错误
[*] 如何明确应用 Java 多线程与并发编程?
[*] 把握Java泛型的艺术:协变、逆变与不可变性一网打尽
[*] Java Spring 中常用的 @PostConstruct 注解使用总结
[*] 如何明确线程安全这个概念?
[*] 明确 Java 桥接方法
[*] Spring 整合嵌入式 Tomcat 容器
[*] Tomcat 如何加载 SpringMVC 组件
[*] “在什么情况下类必要实现 Serializable,什么情况下又不必要(一)?”
[*] “制止序列化灾难:把握实现 Serializable 的原形!(二)”
[*] 如何自定义一个本身的 Spring Boot Starter 组件(从入门到实践)
[*] 解密 Redis:如何通过 IO 多路复用征服高并发挑战!
[*] 线程 vs 假造线程:深入明确及区别
[*] 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
[*] 10大程序员提拔代码优雅度的必杀技,瞬间让你成为团队宠儿!
[*] “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”
[*] Java 中消除 If-else 技巧总结
[*] 线程池的核心参数设置(仅供参考)
[*] 【人工智能】聊聊Transformer,深度学习的一股清流(13)
[*] Java 罗列的几个常用技巧,你可以试着用用
[*] 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)
[*] 如何明确 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的接洽
[*] HTTP、HTTPS、Cookie 和 Session 之间的关系
[*] 使用 Spring 框架构建 MVC 应用程序:初学者教程
[*] 有缺陷的 Java 代码:Java 开辟人员最常犯的 10 大错误
[*] Java Spring 中常用的 @PostConstruct 注解使用总结
[*] 线程 vs 假造线程:深入明确及区别
[*] 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
[*] 10大程序员提拔代码优雅度的必杀技,瞬间让你成为团队宠儿!
[*] 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)
[*] 为什么用了 @Builder 反而报错?深入明确 Lombok 的“暗坑”与解决方案(二)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]