1. 说明
- 一类行为或算法针对不同对象或场景而不同,比如:交通工具都有鸣笛行为,汽车为“滴~滴~”,自行车“铃~铃~”,火车“呜~~~”,轮船“呜~~~”。(这里假设火车和轮船是相同的行为,体现一个策略实现可以复用,并只需要维护一份代码)
- 通常会通过增加类型判断,使用
if...else
的方式区分运行时执行的策略,策略模式就是解决大量if...else
的问题。
策略模式思路:
- 把类似的行为抽象成接口;
- 不同的行为实现实现接口;
- 对象使用接口,通过指定实现类,可快速替换不同策略,同时提高代码复用率和可维护性。
2. 示例
策略接口:
public interface WhistleStrategy {
void whistle();
}
策略实现1:
public class DidiWhistle implements WhistleStrategy {
@Override
public void whistle() {
System.out.println("滴~滴~");
}
}
策略实现2:
public class LinglingWhistle implements WhistleStrategy {
@Override
public void whistle() {
System.out.println("铃~铃~");
}
}
策略实现3:
public class WuWhistle implements WhistleStrategy {
@Override
public void whistle() {
System.out.println("呜~~~");
}
}
抽象对象(具有类似行为):
public abstract class Transport {
private WhistleStrategy whistleStrategy;
protected void setWhistleStrategy(WhistleStrategy whistleStrategy) {
this.whistleStrategy = whistleStrategy;
}
public void move() {
if (whistleStrategy == null) throw new UnsupportedOperationException("未设置鸣笛策略!");
whistleStrategy.whistle();
}
public abstract void display();
}
对象1:
public class Car extends Transport {
public Car() {
super();
setWhistleStrategy(new DidiWhistle());
}
@Override
public void display() {
System.out.println("我是汽车");
}
}
对象2:
public class Bike extends Transport {
public Bike() {
super();
super.setWhistleStrategy(new LinglingWhistle());
}
@Override
public void display() {
System.out.println("我是自行车");
}
}
对象3:
public class Train extends Transport {
public Train() {
super();
super.setWhistleStrategy(new WuWhistle());
}
@Override
public void display() {
System.out.println("我是火车");
}
}
对象4:
public class Ship extends Transport {
public Ship() {
super();
super.setWhistleStrategy(new WuWhistle());
}
@Override
public void display() {
System.out.println("我是轮船");
}
}
测试类:
public class WhistleTest {
public static void main(String[] args) {
Transport transport = null;
transport = new Car();
// transport = new Bike();
// transport = new Train();
// transport = new Ship();
transport.display();
transport.move();
}
}