策略模式要义:一个类的行为或其算法可以在运行时更改。
就好比坦克大战里面吃道具,吃一个道具,便可以在本身基础上在自身上加强。
是不是觉得有点像装饰器模式,但他们有本质的区别:策略模式更倾向是N选1的模式,也即根据条件选择相应的算法,但各种算法是互斥的,装饰模式是在主体逻辑的基础上的附加逻辑,另外,策略模式是不需要与组件有相同的接口的,装饰模式需要装饰器与组件有相同的接口。
下面我们来看看策略模式的实现
需求:现在游戏中有数种鸟,要求实现鸟的叫,展示功能。
创建两只鸟
public abstract class Bird {
public abstract void display();
public void yell() {
System.out.println("吱吱吱.....");
}
}
public class RubberBird extends Bird{
@Override
public void display() {
System.out.println("这是橡皮鸟-----------");
}
}
public class RedHeadBird extends Bird{
@Override
public void display() {
System.out.println("这是 红头鸟。。。");
}
}
实现不同鸟叫功能
public class negtive_01 {
/*===============客户端========================*/
public static void main(String[] args) {
RedHeadBird redHeadBird = new RedHeadBird();
redHeadBird.display();
redHeadBird.yell();
System.out.println(" ");
RubberBird rubberBird = new RubberBird();
rubberBird.display();
rubberBird.yell();
}
}
现在添加一个飞的新功能,但橡皮鸟不会飞,写一个接口实现
public interface Flyable {
void fly();
}
public class RedHeadBird extends Bird implements Flyable{
@Override
public void display() {
System.out.println("这是 红头鸟。。。");
}
@Override
public void fly() {
System.out.println("飞飞飞============");
}
}
这种设计确实实现了需求,但是,这会导致代码的重复,比如:不同的鸟有不同的飞行高度,但是相当部分的鸟又具有相同的高度。这就带来代码重用的问题。
现在我们采用策略模式进行优化
首先写一个策略接口
public interface FlyBehavior {
void fly();
}
实现不同策略
public class FlyByKick implements FlyBehavior{
@Override
public void fly() {
System.out.println("被人踢飞~~~~~~~~~~~");
}
}
public class FlyByWings implements FlyBehavior{
@Override
public void fly() {
System.out.println("用翅膀飞~~~~~~~~~~~");
}
}
依赖注入
public abstract class Bird {
protected FlyBehavior flyBehavior;
public FlyBehavior getFlyBehavior() {
return flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public abstract void display();
public void yell() {
System.out.println("吱吱吱.....");
}
}
public class RedHeadBird extends Bird {
public RedHeadBird() {
this.flyBehavior = new FlyByWings();
}
@Override
public void display() {
System.out.println("这是 红头鸟。。。");
}
public void doFly(){
this.flyBehavior.fly();
}
}
调用实现
public class postive {
/*===============客户端========================*/
public static void main(String[] args) {
RedHeadBird redHeadBird = new RedHeadBird();
redHeadBird.display();
redHeadBird.yell();
redHeadBird.doFly();
System.out.println(" ");
System.out.println("靠近人群中.......");
redHeadBird.setFlyBehavior(new FlyByKick());
redHeadBird.doFly();
}
}
这样我们就完美的进行了策略配置,通过关联另一个接口FlyBehavior,封装飞的行为,同时保证了代码的重用性,接口还可以对扩展保持开放。
是不是很简单呢?
UML类图(以前画的,和本例有所偏差,影响不大放心食用):
业务中存在大量if else场景也可以使用策略模式进行代码块的优化。
这篇文章写得很好,分享给大家
设计完美的策略模式,消除If-else
总结:
策略模式是一种解耦的方法,它对算法进行封装,使得算法的调用和算法本身分离。使用策略模式客户端代码不需要调整,因为多态,算法之间可以互相替换,运行时替换非常实用。