策略模式
Overview
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。
这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。
策略对象改变 context 对象的执行算法。
主要解决
在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用
一个系统有许多许多类,而区分它们的只是他们直接的行为。
应用实例
- 诸葛亮的锦囊妙计,每一个锦囊就是一个策略
- 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略
- JAVA AWT 中的 LayoutManager
优点
- 算法可以自由切换
- 避免使用多重条件判断
- 扩展性良好
注意事项
如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
实现
Behavior
Jump Interface
1 2 3 4 5 6 7 8 9 10 11
| package individual.cy.learn.pattern.behavioral.strategy;
public interface JumpBehavior{
void jump(); }
|
Short Jump
1 2 3 4 5 6 7 8 9 10 11
| package individual.cy.learn.pattern.behavioral.strategy;
public class ShortJump implements JumpBehavior { @Override public void jump() { System.out.println("ShortJump.jump"); } }
|
Long Jump
1 2 3 4 5 6 7 8 9 10 11
| package individual.cy.learn.pattern.behavioral.strategy;
public class LongJump implements JumpBehavior { @Override public void jump() { System.out.println("LongJump.jump"); } }
|
Kick Interface
1 2 3 4 5 6 7 8 9 10 11
| package individual.cy.learn.pattern.behavioral.strategy;
public interface KickBehavior{
void kick(); }
|
Lightning Kick
1 2 3 4 5 6 7 8 9 10 11
| package individual.cy.learn.pattern.behavioral.strategy;
public class LightningKick implements KickBehavior { @Override public void kick() { System.out.println("LightningKick.kick"); } }
|
Tornado Kick
1 2 3 4 5 6 7 8 9 10 11
| package individual.cy.learn.pattern.behavioral.strategy;
public class TornadoKick implements KickBehavior { @Override public void kick() { System.out.println("TornadoKick.kick"); } }
|
Fighter
Fighter Interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package individual.cy.learn.pattern.behavioral.strategy;
public abstract class BaseFighter { protected KickBehavior kickBehavior; protected JumpBehavior jumpBehavior;
public BaseFighter(KickBehavior kickBehavior, JumpBehavior jumpBehavior) { this.kickBehavior = kickBehavior; this.jumpBehavior = jumpBehavior; }
public abstract void display();
public void punch() { System.out.println("BaseFighter.punch"); }
public void roll() { System.out.println("BaseFighter.roll"); }
public void kick() { kickBehavior.kick(); }
public void jump() { jumpBehavior.jump(); }
public void setKickBehavior(KickBehavior kickBehavior) { this.kickBehavior = kickBehavior; }
public void setJumpBehavior(JumpBehavior jumpBehavior) { this.jumpBehavior = jumpBehavior; } }
|
YeWen Fighter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package individual.cy.learn.pattern.behavioral.strategy;
public class YeWenFighter extends BaseFighter { public YeWenFighter(KickBehavior kickBehavior, JumpBehavior jumpBehavior) { super(kickBehavior, jumpBehavior); }
@Override public void display() { System.out.println("YeWenFighter.display"); } }
|
Ken Fighter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package individual.cy.learn.pattern.behavioral.strategy;
public class KenFighter extends BaseFighter { public KenFighter(KickBehavior kickBehavior, JumpBehavior jumpBehavior) { super(kickBehavior, jumpBehavior); }
@Override public void display() { System.out.println("KenFighter.display"); } }
|
Tester
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package individual.cy.learn.pattern.behavioral.strategy;
public class StrategyPatternTester { public static void main(String[] args) { JumpBehavior shortJump = new ShortJump(); JumpBehavior longJump = new LongJump(); KickBehavior tornadoKick = new TornadoKick();
BaseFighter ken = new KenFighter(tornadoKick, shortJump); ken.display();
ken.punch(); ken.roll(); ken.jump(); ken.kick();
ken.setJumpBehavior(longJump); ken.jump();
ken.setKickBehavior(tornadoKick); ken.kick(); } }
|