策略模式
Posted nalanziyi-liner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了策略模式相关的知识,希望对你有一定的参考价值。
策略模式采用组合的形式,把一个算法任务委托给被组合的接口,根据运行时传入对象的不同,算法可以做到相互替换,同时这些变化可以独立于具体的使用者。
例如,一般车上都会有喇叭,不同的车喇叭的声音不一样,将车抽象成一个接口如下:
1 public interface Vehicle 2 void whistle(); //鸣笛 3
我们都知道,自行车按铃是“铃铃铃”的声音,而小汽车则是“嘀嘀”声,它们都实现了Vehicle接口:
1 public class Bike implements Vehicle 2 public void whistle() 3 System.out.println("铃铃铃。。。"); 4 5 6 7 public class implements Vehicle 8 public void whistle() 9 System.out.println("嘀嘀。。。"); 10 11
现在,自行车和小汽车都能够正常的鸣笛了。然而,这种类结构有一个问题,假设小汽车的喇叭坏了,这个时候调用它的 whistle 方法没有发出任何声音,我们需要换一个喇叭。然而由于 whistle 方法是与具体的车(Car)绑定在一起了,要换喇叭,只能连车一起换了,这显然不划算,所以需要将喇叭与车进行重新设计,让喇叭只是作为车里面的一个可以随时更换的配件。让喇叭作为一个接口独立出来,并且在车里放置一个喇叭对象,需要鸣笛的时候,将鸣笛的任务交给喇叭就可以了。
首先,抽象出来一个喇叭接口:
1 public interface Horn 2 void ring(); //喇叭会响 3
每个车也都需要一个喇叭:
1 public interface Vehicle 2 Horn horn; 3 void whistle(); //鸣笛 4
然后,针对自行车和小汽车,分别设计各自的车铃:
1 // 自行车铃 2 public class Bicyclebell implements Horn 3 public void ring() 4 System.out.println("铃铃铃。。。"); 5 6 7 8 // 汽车车铃 9 public class CarbellDiDi implements Horn 10 public void ring() 11 System.out.println("嘀嘀。。。"); 12 13 14 15 // 汽车车铃 16 public class CarbellBaBa implements Horn 17 public void ring() 18 System.out.println("叭叭。。。"); 19 20
接着在自行车和汽车上都放置一个车铃:
1 public class Bike implements Vehicle 2 // 自行车需要自行车车铃 3 public Bike() 4 this.horn = new Bicyclebell(); 5 6 7 public void whistle() 8 horn.ring(); 9 10 11 public void setHorn(Horn horn) 12 this.horn = horn; 13 14 15 16 public class Car implements Vehicle 17 // 汽车需要汽车铃 18 public Car() 19 this.horn = new CarBellDiDi(); 20 21 22 public void whistle() 23 horn.ring(); 24 25 26 public void setHorn(Horn horn) 27 this.horn = horn; 28 29
接下来写一段程序测试一下我们的代码,看看是否能够达到预期:
1 public static void main(String[] args) 2 Vehicle bike = new Bike(); 3 bike.whistle(); // 铃铃铃。。。 4 5 Vehicle car = new Car(); 6 car.whistle(); // 嘀嘀。。。 7 8 //给汽车换个喇叭 9 car.setHorn(new CarbellBaBa()); 10 car.whistle(); //叭叭。。。 11
可以看到,自行车和汽车成功的鸣笛了,并且我们成功地给汽车换了个喇叭。当然,可以看到子类中的whistle方法代码逻辑都一样,有些重复,我们完全可以将Vehicle变成一个抽象类,然后在其whistle方法里调用horn的ring方法,这样就可以减少许多冗余的代码,不过这不是本文的重点,这种实现方式暂且略过。
现在重新审视一下这个设计,不同的车铃对应着不同的策略,而车则是策略的使用者,通过组合的方式,实现了策略与使用者之间的解耦,并且通过setter方法可以动态的更改策略,这种做法便是运用了策略模式。
参考:<<Head First设计模式>>
以上是关于策略模式的主要内容,如果未能解决你的问题,请参考以下文章