策略模式的缺点,你知道的有哪些?

目录

1.什么是策略模式

2.策略模式有什么缺点

2.1 增加系统的复杂性

2.2 客户端需要了解不同的策略

2.3 策略切换开销

2.4 策略的冗余

2.5 违反开闭原则


1.什么是策略模式

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装到独立的策略类中,使得它们可以互相替换。它可以提高代码的可维护性和灵活性。

2.策略模式有什么缺点

2.1 增加系统的复杂性

假设我们要开发一个电商平台,它需要计算订单的运费。为了适应不同的运费计算规则,我们使用策略模式,每个运费规则是一个策略类。

  • FreeShippingStrategy:免费配送策略。
  • FlatRateShippingStrategy:固定运费策略。
  • WeightBasedShippingStrategy:基于重量的运费策略。
  • DistanceBasedShippingStrategy:基于距离的运费策略。

存在的问题:

随着业务的扩展,我们可能需要添加更多的运费策略(例如基于会员等级、节假日优惠等),导致系统中策略类的数量急剧增加,类的管理变得复杂,难以维护。

2.2 客户端需要了解不同的策略

针对上述电商系统,现在有一个客户端需要选择合适的运费策略,那么客户端代码必须了解所有的运费策略,并根据不同的订单条件来选择合适的策略。例如:

if (order.isFree()) {
    shippingStrategy = new FreeShippingStrategy();
} else if (order.isDistance()) {
    shippingStrategy = new DishtanceBasedShippingStrategy();
} else if (order.isHeavy()) {
    shippingStrategy = new WeightBasedShippingStrategy();
} else {
    shippingStrategy = new FlatRateShippingStrategy();
}

存在的问题:

这种情况下,客户端代码变得复杂,且增加了策略选择的逻辑。如果以后有新的运费策略,还需要修改客户端代码,违反了开闭原则。

2.3 策略切换开销

假设有一个实时推荐系统,它根据用户的行为数据实时调整推荐算法(策略)。推荐算法可能包括基于协同过滤的策略、基于内容的策略、基于用户历史的策略等。

存在的问题:

如果推荐系统在短时间内需要频繁地切换策略,例如每分钟都需要重新评估并选择不同的推荐算法,就会导致频繁的策略实例化和销毁,增加系统的性能开销。

2.4 策略的冗余

假设我们有一个人力资源系统,负责计算不同类型员工的薪资。为了灵活应对各种薪资的计算规则,我们使用策略模式,每个薪资计算规则都被封装为一个策略类。

  • FullTimeEmployeeSalaryStrategy:全职员工薪资计算策略。
  • PartTimeEmployeeSalaryStrategy:兼职员工薪资计算策略。
  • ContractorSalaryStrategy:合同工薪资计算策略。

 策略类的实现:

// 全职员工薪资策略
public class FullTimeEmployeeSalaryStrategy implements SalaryStrategy {
    @Override
    public double calculateSalary(Employee employee) {
        return employee.getBaseSalary() + employee.getBonus();
    }
}

// 兼职员工薪资策略
public class PartTimeEmployeeSalaryStrategy implements SalaryStrategy {
    @Override
    public double calculateSalary(Employee employee) {
        return employee.getHourlyRate() * employee.getHoursWorked();
    }
}

// 合同工薪资策略
public class ContractorSalaryStrategy implements SalaryStrategy {
    @Override
    public double calculateSalary(Employee employee) {
        return employee.getHourlyRate() * employee.getHoursWorked() + employee.getContractBonus();
    }
}

存在的问题:

假设后来公司决定引入另一种员工类型,比如实习生,他们的薪资计算与兼职员工非常相似,只是薪资中需要额外考虑一个小额的交通补贴。

我们可能会因此创建一个新的策略类 InternSalaryStrategy,实现如下:

// 实习生薪资策略
public class InternSalaryStrategy implements SalaryStrategy {
    @Override
    public double calculateSalary(Employee employee) {
        return employee.getHourlyRate() * employee.getHoursWorked() + employee.getTransportationAllowance();
    }
}

以上大部分代码都是相同的。随着员工类型的增加,这种冗余会更加明显,导致维护这些策略类变得困难,增加了系统的复杂度。

2.5 违反开闭原则

假设我们在一个支付系统中使用策略模式来处理不同的支付方式,每个支付方式是一个策略类,例如信用卡支付、支付宝支付、微信支付等。

存在的问题:

如果我们想要增加一种新的支付方式(例如比特币支付),我们不仅需要增加一个新的策略类,还需要修改客户端代码以支持这种新的支付方式。这样就不符合开闭原则了(对扩展开放,对修改关闭)。

public class PaymentProcessor {
    public void processPayment(Order order) {
        PaymentStrategy strategy;
        switch (order.getPaymentType()) {
            case "CreditCard":
                strategy = new CreditCardPaymentStrategy();
                break;
            case "Alipay":
                strategy = new AlipayPaymentStrategy();
                break;
            case "WeChatPay":
                strategy = new WeChatPayPaymentStrategy();
                break;
            case "Bitcoin": // 新增支付方式
                strategy = new BitcoinPaymentStrategy();
                break;
            default:
                throw new UnsupportedOperationException("不支持的支付方式!!");
        }
        strategy.pay(order);
    }
}

每当新增一种支付方式时,都需要修改 PaymentProcessor 类中的 switch 语句,这违背了开闭原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Master_hl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值