在软件开发中,设计模式被广泛应用于解决各种常见问题,提高代码的可维护性、可扩展性和可读性。工厂模式(Factory Pattern)和策略模式(Strategy Pattern)是两种非常重要的设计模式,它们解决了不同的设计问题,并且在许多情况下可以结合使用。本篇文章将详细讲解工厂模式和策略模式的概念、区别、在Java中的应用场景及其源码实现,帮助开发者更好地理解并运用这些模式。
工厂模式是一种创建型设计模式,提供了一种创建对象的接口,但允许子类决定实例化哪一个类。工厂模式将对象的实例化过程抽象出来,使得客户端代码与具体类的实现解耦。
工厂模式可以分为三类:
优点:
缺点:
策略模式是一种行为型设计模式,定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端而变化。
策略模式主要包含以下角色:
优点:
缺点:
接下来,我们通过一个具体的Java实例来演示工厂模式的实现。假设我们需要创建不同类型的支付方式(如支付宝支付、微信支付、银行卡支付),可以使用工厂模式来实现。
// 定义支付接口
interface Payment {
void pay(double amount);
}
// 实现支付宝支付
class Alipay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付" + amount + "元");
}
}
// 实现微信支付
class WeChatPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用微信支付" + amount + "元");
}
}
// 实现银行卡支付
class BankCardPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用银行卡支付" + amount + "元");
}
}
// 工厂类
class PaymentFactory {
public static Payment createPayment(String type) {
switch (type) {
case "Alipay":
return new Alipay();
case "WeChatPay":
return new WeChatPay();
case "BankCard":
return new BankCardPay();
default:
throw new IllegalArgumentException("不支持的支付类型");
}
}
}
// 客户端代码
public class SimpleFactoryDemo {
public static void main(String[] args) {
Payment payment = PaymentFactory.createPayment("Alipay");
payment.pay(100.0);
}
}
在这个例子中,PaymentFactory
类根据传入的类型创建不同的支付方式对象。客户端只需调用工厂类的createPayment
方法即可获得所需的支付对象,无需关心对象的具体实现。
// 抽象工厂接口
interface PaymentFactoryMethod {
Payment createPayment();
}
// 实现支付宝支付工厂
class AlipayFactory implements PaymentFactoryMethod {
@Override
public Payment createPayment() {
return new Alipay();
}
}
// 实现微信支付工厂
class WeChatPayFactory implements PaymentFactoryMethod {
@Override
public Payment createPayment() {
return new WeChatPay();
}
}
// 实现银行卡支付工厂
class BankCardPayFactory implements PaymentFactoryMethod {
@Override
public Payment createPayment() {
return new BankCardPay();
}
}
// 客户端代码
public class FactoryMethodDemo {
public static void main(String[] args) {
PaymentFactoryMethod factory = new AlipayFactory();
Payment payment = factory.createPayment();
payment.pay(200.0);
}
}
在工厂方法模式中,每个具体的支付方式都有自己的工厂类,负责创建对应的支付对象。客户端通过工厂接口获得支付对象,这样更符合开闭原则,添加新的支付方式时无需修改现有代码。
抽象工厂模式在实际应用中通常用于创建一系列相关或相互依赖的对象。在支付系统中,如果我们还要创建不同支付方式的验证器(如支付宝验证器、微信验证器等),可以使用抽象工厂模式。
// 验证器接口
interface Validator {
void validate();
}
// 支付接口同上
// 支付和验证器抽象工厂接口
interface PaymentValidatorFactory {
Payment createPayment();
Validator createValidator();
}
// 支付宝支付工厂实现
class AlipayFactory implements PaymentValidatorFactory {
@Override
public Payment createPayment() {
return new Alipay();
}
@Override
public Validator createValidator() {
return new AlipayValidator();
}
}
// 微信支付工厂实现
class WeChatPayFactory implements PaymentValidatorFactory {
@Override
public Payment createPayment() {
return new WeChatPay();
}
@Override
public Validator createValidator() {
return new WeChatValidator();
}
}
// 银行卡支付工厂实现
class BankCardPayFactory implements PaymentValidatorFactory {
@Override
public Payment createPayment() {
return new BankCardPay();
}
@Override
public Validator createValidator() {
return new BankCardValidator();
}
}
// 支付宝验证器
class AlipayValidator implements Validator {
@Override
public void validate() {
System.out.println("支付宝支付验证成功");
}
}
// 微信
验证器
class WeChatValidator implements Validator {
@Override
public void validate() {
System.out.println("微信支付验证成功");
}
}
// 银行卡验证器
class BankCardValidator implements Validator {
@Override
public void validate() {
System.out.println("银行卡支付验证成功");
}
}
// 客户端代码
public class AbstractFactoryDemo {
public static void main(String[] args) {
PaymentValidatorFactory factory = new AlipayFactory();
Payment payment = factory.createPayment();
Validator validator = factory.createValidator();
validator.validate();
payment.pay(300.0);
}
}
在抽象工厂模式中,PaymentValidatorFactory
接口定义了创建支付对象和验证器对象的方法。每个具体的工厂实现都负责创建对应的支付方式和验证器。这样,当我们需要创建一组相关的对象时,抽象工厂模式提供了一个统一的接口,保证了相关对象的一致性。
策略模式通常用于在运行时选择不同的算法或行为。接下来,我们通过一个计算价格的例子来展示策略模式的实现。
假设我们有一个购物系统,不同的用户类型享有不同的折扣策略(如普通用户、VIP用户、超级VIP用户),我们可以使用策略模式来实现这些折扣策略。
// 折扣策略接口
interface DiscountStrategy {
double calculateDiscount(double price);
}
// 普通用户折扣策略
class RegularDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price; // 没有折扣
}
}
// VIP用户折扣策略
class VIPDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.9; // 10% 折扣
}
}
// 超级VIP用户折扣策略
class SuperVIPDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.8; // 20% 折扣
}
}
// 上下文类
class PriceCalculator {
private DiscountStrategy discountStrategy;
public PriceCalculator(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
public double calculateFinalPrice(double price) {
return discountStrategy.calculateDiscount(price);
}
}
// 客户端代码
public class StrategyPatternDemo {
public static void main(String[] args) {
double price = 100.0;
// 普通用户价格
PriceCalculator regularCalculator = new PriceCalculator(new RegularDiscountStrategy());
System.out.println("普通用户价格: " + regularCalculator.calculateFinalPrice(price));
// VIP用户价格
PriceCalculator vipCalculator = new PriceCalculator(new VIPDiscountStrategy());
System.out.println("VIP用户价格: " + vipCalculator.calculateFinalPrice(price));
// 超级VIP用户价格
PriceCalculator superVipCalculator = new PriceCalculator(new SuperVIPDiscountStrategy());
System.out.println("超级VIP用户价格: " + superVipCalculator.calculateFinalPrice(price));
}
}
在这个例子中,DiscountStrategy
接口定义了一个折扣计算方法,具体的折扣策略由RegularDiscountStrategy
、VIPDiscountStrategy
和SuperVIPDiscountStrategy
类实现。PriceCalculator
类作为上下文类,持有一个DiscountStrategy
的引用,通过调用策略的calculateDiscount
方法来计算最终价格。
策略模式的一个优势是可以在运行时动态切换策略。我们可以通过修改PriceCalculator
中的策略实现来达到这一目的。
// 客户端代码
public class DynamicStrategyDemo {
public static void main(String[] args) {
double price = 150.0;
PriceCalculator calculator = new PriceCalculator(new RegularDiscountStrategy());
System.out.println("普通用户价格: " + calculator.calculateFinalPrice(price));
// 动态切换为VIP策略
calculator = new PriceCalculator(new VIPDiscountStrategy());
System.out.println("VIP用户价格: " + calculator.calculateFinalPrice(price));
// 动态切换为超级VIP策略
calculator = new PriceCalculator(new SuperVIPDiscountStrategy());
System.out.println("超级VIP用户价格: " + calculator.calculateFinalPrice(price));
}
}
在这个例子中,PriceCalculator
可以在运行时切换不同的折扣策略。这样,当系统需要根据不同的用户类型应用不同的折扣时,可以灵活地调整策略,而无需修改现有代码。
策略模式和工厂模式可以结合使用,以便在创建上下文类时动态选择和设置策略。假设我们将折扣策略的选择逻辑抽象到一个工厂类中。
// 折扣策略工厂
class DiscountStrategyFactory {
public static DiscountStrategy getStrategy(String userType) {
switch (userType) {
case "Regular":
return new RegularDiscountStrategy();
case "VIP":
return new VIPDiscountStrategy();
case "SuperVIP":
return new SuperVIPDiscountStrategy();
default:
throw new IllegalArgumentException("未知的用户类型");
}
}
}
// 客户端代码
public class StrategyFactoryDemo {
public static void main(String[] args) {
double price = 200.0;
// 根据用户类型选择策略
DiscountStrategy strategy = DiscountStrategyFactory.getStrategy("VIP");
PriceCalculator calculator = new PriceCalculator(strategy);
System.out.println("VIP用户价格: " + calculator.calculateFinalPrice(price));
}
}
在这个例子中,DiscountStrategyFactory
类根据用户类型返回相应的折扣策略。通过结合工厂模式和策略模式,我们可以将策略的选择逻辑集中到工厂类中,使得代码更加简洁和灵活。
在支付系统中,工厂模式通常用于创建支付方式对象,例如不同的支付渠道(支付宝、微信、银行卡等)。策略模式则可以用于选择不同的支付策略,例如不同的折扣策略、手续费计算策略等。
在电商系统中,工厂模式和策略模式都可以应用于订单处理、物流选择、商品推荐等多个环节。
在权限管理系统中,工厂模式可以用于创建不同的权限对象,而策略模式可以用于定义不同的权限控制策略。
工厂模式和策略模式是Java设计模式中两种常见且重要的模式。它们分别用于解决对象创建和行为选择的问题。在实践中,工厂模式和策略模式常常可以结合使用,通过工厂模式生成不同的对象实例,再通过策略模式动态选择行为或算法。这种组合使用可以有效提升系统的灵活性和可维护性。
通过本篇文章的详细讲解和代码示例,我们理解了工厂模式与策略模式的核心思想、应用场景以及如何在Java中实现这些模式。在实际开发中,掌握并合理运用工厂模式和策略模式,可以帮助开发者设计出更加优雅、可扩展的系统。