策略模式/Strategy

策略模式/Strategy

意图/适用场景:

策略模式是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以互换。这样做的好处是,客户端可以以插件的方式更换算法。

电子商务网站的购物车系统是一个策略模式非常适用的场景:比如,在优惠方式上,某一类商品是每件优惠一元,另一类商品是折扣5%,还有一类商品也是打折,但折扣幅度是10%。所以需要应用不同的优惠算法来计算最终的价格。

在这个系统中,可以想象到会有一个计算者角色(与本模式中的Context相同功能),它负责计算价格。但如果把所有的算法都放在它里面来实现的话,会比较混乱。如果应用策略模式的话,就可以把行为和上下文环境分开。上下文类(计算者)中负责维持和查询行为类,各种算法则在具体策略类中提供。由于算法和环境独立开来,算法的增减、修改都不会影响到上下文和客户端。这也为上下文类减轻了负担。

UML:

策略模式/Strategy

参与者:

  1. 上下文角色(Context):持有一个Strategy类的引用。
  2. 抽象策略角色(Strategy):抽象角色,通常是一个接口或者抽象类。定义出所有的具体策略类的公共接口。如果具体策略类有共同的行为,可以把Strategy定义为抽象类,并实现这些公共的行为;否则最好定义为接口。
  3. 具体策略(ConcreteStrategy):包装了相关的算法或行为。

要点:

在下面的情况下应当考虑使用策略模式:

  1. 系统需要动态地在多种算法中选择一种;
  2. 算法很多,如果由一个角色来处理的话,逻辑会非常混乱;
  3. 算法不可让客户端知道。

策略模式的最大优点在于把算法分门别类,由不同的实体类来维护,实现了算法本身与算法的使用者之间的弱耦合。而且把一个搅在一起的大算法分而治之,避免了大量使用条件而造成的混乱。

应用实例:

排序策略系统,参见《Java与模式》本章。

策略模式/Strategy

相关模式:

以下模式在结构上与策略模式相似,它们的区别多半在于用意不同,适用的场景是不同的。

  1. 策略模式:强调的是算法的分治与选择。
  2. 建造模式:它的核心功能是以一步一步的方式创建一个产品,把各个零件分别制造并组装起来,最后形成一个产品。
  3. 适配模式:它的用意在于把不同接口的对象“转接”成客户端所需要的接口。
  4. 装饰模式:它的用意在于在不改变接口的情况下,增强一个对象的功能。

示例代码:

[java]
// Source code from file:  ConcreteStrategyA.java

package designPatterns.Strategy;

public class ConcreteStrategyA implements Strategy {
public void strategy() {
System.out.println("ConcreteStrategyA.strategy()");
}
}

// Source code from file:  ConcreteStrategyB.java

package designPatterns.Strategy;

public class ConcreteStrategyB implements Strategy {
public void strategy() {
System.out.println("ConcreteStrategyA.strategy()");
}
}

// Source code from file:  Context.java

package designPatterns.Strategy;

public class Context {
private Strategy strategy;

public void strategy(char type) {
if ('A' == type)
strategy = new ConcreteStrategyA();
else if ('B' == type)
strategy = new ConcreteStrategyB();
strategy.strategy();
}
}

// Source code from file:  Strategy.java

package designPatterns.Strategy;

public interface Strategy {
public void strategy();
}

// Source code from file:  User.java

package designPatterns.Strategy;

public class User {
public static void main(String[] args) {
Context ctxt = new Context();
ctxt.strategy('A');
ctxt.strategy('B');
}
}
[/java]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值