策略模式-Java描述

概述

在策略模式中,我们可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法,在这里,每一个封装算法的类我们都可以称之为一种策略(Strategy),为了保证这些策略在使用时具有一致性,一般会提供一个抽象的策略类来做规则的定义,而每种算法则对应于一个具体策略类。

策略模式的主要目的是将算法的定义与使用分开,也就是将算法的行为和环境分开,将算法的定义放在专门的策略类中,每一个策略类封装了一种实现算法,使用算法的环境类针对抽象策略类进行编程,符合“依赖倒转原则”。在出现新的算法时,只需要增加一个新的实现了抽象策略类的具体策略类即可。策略模式定义如下: 策略模式(Strategy Pattern):定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。策略模式是一种对象行为型模式。

  • 结构如图
    在这里插入图片描述
  • 在策略模式结构图中包含如下几个角色:
  1. Context(环境类):环境类是使用算法的角色,它在解决某个问题(即实现某个方法)时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。
  2. Strategy(抽象策略类):它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。
  3. ConcreteStrategy(具体策略类):它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。

策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列具体策略类里面,作为抽象策略类的子类。在策略模式中,对环境类和抽象策略类的理解非常重要,环境类是需要使用算法的类。在一个系统中可以存在多个环境类,它们可能需要重用一些相同的算法。

  1. Strategy
abstract class AbstractStrategy {
public abstract void algorithm(); //声明抽象算法
}
  1. ConcreteStrategyA
class ConcreteStrategyA extends AbstractStrategy {
//算法的具体实现
public void algorithm() {
//算法A
}
}
  1. Context
class Context {
private AbstractStrategy strategy; //维持一个对抽象策略类的引用
public void setStrategy(AbstractStrategy strategy) {
this.strategy= strategy;
}
//调用策略类中的算法
public void algorithm() {
strategy.algorithm();
}
}
  1. 客戶端
Context context = new Context();
AbstractStrategy strategy;
strategy = new ConcreteStrategyA(); //可在运行时指定类型
context.setStrategy(strategy);
context.algorithm();

案例实践

某软件公司欲开发一款飞机模拟系统,该系统主要模拟不同种类飞机的飞行特征与起飞特征,需要模拟的飞机种类及其特征如表1所示:
表1 飞机种类及特征一览表。为将来能够模拟更多种类的飞机,试采用策略模式设计并模拟实现该飞机模拟系统。
在这里插入图片描述

  • Strategy
public interface PlanStrategy {
    public void algorithm();
}
  • ConcreteStrategyA
public class Helicopter implements PlanStrategy {

    @Override
    public void algorithm() {
        System.out.println("直升机:垂直起飞、亚音速飞行");
    }
}
  • ConcreteStrategyB
public class Aircraft implements PlanStrategy {
    @Override
    public void algorithm() {
        System.out.println("客机:长距离起飞、亚音速飞行");
    }
}
  • Context
public class Context {
    private PlanStrategy planStrategy;

    public void setplanStrategy(PlanStrategy planStrategy) {
        this.planStrategy = planStrategy;
    }

    public void planalgorithm(){
        planStrategy.algorithm();
    }
}
  • 客户端Client
public class Client {
    public static void main(String[] args) {
        Context context=new Context();
        PlanStrategy aircraftStrategy=new Aircraft();
        context.setplanStrategy(aircraftStrategy);
        context.planalgorithm();

    }
}

在这里插入图片描述

总结

  • 主要优点
    (1) 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
    (2) 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到抽象策略类中,从而避免重复的代码。
    (3) 策略模式提供了一种可以替换继承关系的办法。如果不使用策略模式,那么使用算法的环境类就可能会有一些子类,每一个子类提供一种不同的算法。但是,这样一来算法的使用就和算法本身混在一起,不符合“单一职责原则”,决定使用哪一种算法的逻辑和该算法本身混合在一起,从而不可能再独立演化;而且使用继承无法实现算法或行为在程序运行时的动态切换。
    (4) 使用策略模式可以避免多重条件选择语句。多重条件选择语句不易维护,它把采取哪一种算法或行为的逻辑与算法或行为本身的实现逻辑混合在一起,将它们全部硬编码(Hard Coding)在一个庞大的多重条件选择语句中,比直接继承环境类的办法还要原始和落后。
    (5) 策略模式提供了一种算法的复用机制,由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略类。

  • 主要缺点
    (1) 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
    (2) 策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类。
    (3) 无法同时在客户端使用多个策略类,也就是说,在使用策略模式时,客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。

  • 适用场景
    (1) 一个系统需要动态地在几种算法中选择一种,那么可以将这些算法封装到一个个的具体算法类中,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,根据“里氏代换原则”和面向对象的多态性,客户端可以选择使用任何一个具体算法类,并只需要维持一个数据类型是抽象算法类的对象。
    (2) 一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句。
    (3) 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法与相关的数据结构,可以提高算法的保密性与安全性。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
策略模式可以用来描述四则运算,具体实现方法如下: 1. 定义一个接口或抽象类,包含一个计算方法calculate(),用来执行具体的四则运算。 2. 实现四个具体的策略类,分别代表加法、减法、乘法和除法操作,这些类都实现了calculate()方法。 3. 定义一个上下文类,它包含一个具体的策略对象,根据需要调用策略对象的calculate()方法来进行计算。 4. 在客户端代码中,根据输入的运算符号创建相应的策略对象,并将其传递给上下文对象,然后调用上下文对象的calculate()方法执行四则运算。 下面是具体的实现代码: ```java // 定义四则运算接口 public interface Operation { int calculate(int a, int b); } // 实现加法策略类 public class AddOperation implements Operation { @Override public int calculate(int a, int b) { return a + b; } } // 实现减法策略类 public class SubOperation implements Operation { @Override public int calculate(int a, int b) { return a - b; } } // 实现乘法策略类 public class MulOperation implements Operation { @Override public int calculate(int a, int b) { return a * b; } } // 实现除法策略类 public class DivOperation implements Operation { @Override public int calculate(int a, int b) { if (b == 0) { throw new IllegalArgumentException("除数不能为0"); } return a / b; } } // 上下文类 public class Calculator { private Operation operation; public Calculator(Operation operation) { this.operation = operation; } public int calculate(int a, int b) { return operation.calculate(a, b); } } // 客户端代码 public class Client { public static void main(String[] args) { char operator = '+'; int a = 10, b = 5; Operation operation; switch (operator) { case '+': operation = new AddOperation(); break; case '-': operation = new SubOperation(); break; case '*': operation = new MulOperation(); break; case '/': operation = new DivOperation(); break; default: throw new IllegalArgumentException("不支持的运算符:" + operator); } Calculator calculator = new Calculator(operation); int result = calculator.calculate(a, b); System.out.printf("%d %c %d = %d", a, operator, b, result); } } ``` 以上代码实现了四则运算的策略模式,通过修改客户端代码中的运算符号,可以实现不同的运算。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值