java设计模式--策略模式详解
策略模式
策略模式(Strategy Pattern)属于行为型模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。用算法族分别封装起来,实现同一个接口,让他们之间可以互相替换,让算法的变化独立于使用算法的客户。
- 主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
- 如何解决:将这些算法封装成一个一个的类,任意地替换。
- 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
使用场景:
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
- 一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
| 优点 | 缺点 |
|---|---|
| 算法可以自由切换 | 策略类会增多 |
| 避免使用多重条件判断 | 所有策略类都需要对外暴露 |
| 扩展性良好 |

- 环境类(Context):持有抽象策略类的引用,用来操作策略的上下文环境。
- 抽象策略类(Strategy):策略的抽象类或接口,给出所需实现接口。
- 具体策略类(ConcreteStrategy):具体的策略实现。
Demo
有几种鹅:天鹅、野鹅、灰鹅,鹅有各种行为,如飞、游泳、叫等。
假设天鹅灰鹅飞行能力一般,野鹅飞行能力优秀;天鹅野鹅游泳能力一般,灰鹅游泳能力优秀。
首先看第一种方法:

这种方法固然可以实现目的,但问题显而易见,子类过多覆盖父类方法,代码未复用,耦合度很高。使用策略模式,简单来说,就是封装子类行为成接口,父类包含该接口即可。

代码:
public interface FlyBehavior {
void fly();
}
public class FlyGood implements FlyBehavior {
@Override
public void fly() {
System.out.println("飞行能力优秀");
}
}
public class FlyNormal implements FlyBehavior {
@Override
public void fly() {
System.out.println("飞行能力一般");
}
}
public interface SwimBehavior {
void swim();
}
public class SwimGood implements SwimBehavior {
@Override
public void swim() {
System.out.println("游得好");
}
}
public class SwimNormal implements SwimBehavior {
@Override
public void swim() {
System.out.println("游得一般");
}
}
public abstract class Goose {
//策略接口
FlyBehavior flyBehavior;
SwimBehavior swimBehavior;
//其他属性等...
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setSwimBehavior(SwimBehavior swimBehavior) {
this.swimBehavior = swimBehavior;
}
}
public class Swan extends Goose{
public Swan() {
flyBehavior=new FlyNormal();
swimBehavior=new SwimNormal();
}
}
public class WildGoose extends Goose{
public WildGoose() {
flyBehavior=new FlyGood();
swimBehavior=new SwimNormal();
}
}
public class GreyGoose extends Goose{
public GreyGoose() {
flyBehavior=new FlyNormal();
swimBehavior=new SwimGood();
}
}
public class Client {
public static void main(String[] args) {
Swan swan=new Swan();
swan.flyBehavior.fly();
WildGoose wildGoose=new WildGoose();
wildGoose.swimBehavior.swim();
GreyGoose greyGoose=new GreyGoose();
greyGoose.flyBehavior.fly();
greyGoose.setFlyBehavior(new FlyGood()); //改变某个对象的行为
greyGoose.flyBehavior.fly();
}
}
运行结果:

总结
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
相关文章
Java遍历输出指定目录、树形结构所有文件包括子目录下的文件
这篇文章主要介绍了Java遍历输出指定目录、树形结构下的所有文件包括子目录中的文件,需要的朋友可以参考下2015-07-07
SpringCloud Gateway的路由,过滤器和限流解读
这篇文章主要介绍了SpringCloud Gateway的路由,过滤器和限流解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2023-02-02
SpringBoot自定义HttpMessageConverter操作
这篇文章主要介绍了SpringBoot自定义HttpMessageConverter的操作,具有很好的参考价值,如有错误或未考虑完全的地方,望不吝赐教2021-08-08
详解SpringBoot基于Dubbo和Seata的分布式事务解决方案
这篇文章主要介绍了详解SpringBoot基于Dubbo和Seata的分布式事务解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-10-10
SpringBoot如何读取war包jar包和Resource资源
这篇文章主要介绍了SpringBoot如何读取war包jar包和Resource资源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2020-01-01
Java 中jasperReport实现动态列打印的实现代码
这篇文章主要介绍了Java 中jasperReport实现动态列打印的实现代码的相关资料,希望通过本文大家能掌握这部分内容,需要的朋友可以参考下2017-09-09


最新评论