经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
策略模式
来源:cnblogs  作者:纳兰小依  时间:2019/9/16 9:17:44  对本文有异议

      策略模式采用组合的形式,把一个算法任务委托给被组合的接口,根据运行时传入对象的不同,算法可以做到相互替换,同时这些变化可以独立于具体的使用者。

      例如,一般车上都会有喇叭,不同的车喇叭的声音不一样,将车抽象成一个接口如下:

  1. 1 public interface Vehicle{
  2. 2 void whistle(); //鸣笛
  3. 3 }

      我们都知道,自行车按铃是“铃铃铃”的声音,而小汽车则是“嘀嘀”声,它们都实现了Vehicle接口:

  1. 1 public class Bike implements Vehicle{
  2. 2 public void whistle(){
  3. 3 System.out.println("铃铃铃。。。");
  4. 4 }
  5. 5 }
  6. 6
  7. 7 public class implements Vehicle{
  8. 8 public void whistle(){
  9. 9 System.out.println("嘀嘀。。。");
  10. 10 }
  11. 11 }

      现在,自行车和小汽车都能够正常的鸣笛了。然而,这种类结构有一个问题,假设小汽车的喇叭坏了,这个时候调用它的 whistle 方法没有发出任何声音,我们需要换一个喇叭。然而由于 whistle 方法是与具体的车(Car)绑定在一起了,要换喇叭,只能连车一起换了,这显然不划算,所以需要将喇叭与车进行重新设计,让喇叭只是作为车里面的一个可以随时更换的配件。让喇叭作为一个接口独立出来,并且在车里放置一个喇叭对象,需要鸣笛的时候,将鸣笛的任务交给喇叭就可以了。

      首先,抽象出来一个喇叭接口:

  1. 1 public interface Horn{
  2. 2 void ring(); //喇叭会响
  3. 3 }

      每个车也都需要一个喇叭:

  1. 1 public interface Vehicle{
  2. 2 Horn horn;
  3. 3 void whistle(); //鸣笛
  4. 4 }

      然后,针对自行车和小汽车,分别设计各自的车铃:

  1. 1 // 自行车铃
  2. 2 public class Bicyclebell implements Horn{
  3. 3 public void ring(){
  4. 4 System.out.println("铃铃铃。。。");
  5. 5 }
  6. 6 }
  7. 7
  8. 8 // 汽车车铃
  9. 9 public class CarbellDiDi implements Horn{
  10. 10 public void ring(){
  11. 11 System.out.println("嘀嘀。。。");
  12. 12 }
  13. 13 }
  14. 14
  15. 15 // 汽车车铃
  16. 16 public class CarbellBaBa implements Horn{
  17. 17 public void ring(){
  18. 18 System.out.println("叭叭。。。");
  19. 19 }
  20. 20 }

      接着在自行车和汽车上都放置一个车铃:

  1. 1 public class Bike implements Vehicle{
  2. 2 // 自行车需要自行车车铃
  3. 3 public Bike(){
  4. 4 this.horn = new Bicyclebell();
  5. 5 }
  6. 6
  7. 7 public void whistle(){
  8. 8 horn.ring();
  9. 9 }
  10. 10
  11. 11 public void setHorn(Horn horn){
  12. 12 this.horn = horn;
  13. 13 }
  14. 14 }
  15. 15
  16. 16 public class Car implements Vehicle{
  17. 17 // 汽车需要汽车铃
  18. 18 public Car(){
  19. 19 this.horn = new CarBellDiDi();
  20. 20 }
  21. 21
  22. 22 public void whistle(){
  23. 23 horn.ring();
  24. 24 }
  25. 25
  26. 26 public void setHorn(Horn horn){
  27. 27 this.horn = horn;
  28. 28 }
  29. 29 }

      接下来写一段程序测试一下我们的代码,看看是否能够达到预期:

  1. 1 public static void main(String[] args){
  2. 2 Vehicle bike = new Bike();
  3. 3 bike.whistle(); // 铃铃铃。。。
  4. 4
  5. 5 Vehicle car = new Car();
  6. 6 car.whistle(); // 嘀嘀。。。
  7. 7
  8. 8 //给汽车换个喇叭
  9. 9 car.setHorn(new CarbellBaBa());
  10. 10 car.whistle(); //叭叭。。。
  11. 11 }

      可以看到,自行车和汽车成功的鸣笛了,并且我们成功地给汽车换了个喇叭。当然,可以看到子类中的whistle方法代码逻辑都一样,有些重复,我们完全可以将Vehicle变成一个抽象类,然后在其whistle方法里调用horn的ring方法,这样就可以减少许多冗余的代码,不过这不是本文的重点,这种实现方式暂且略过。

      现在重新审视一下这个设计,不同的车铃对应着不同的策略,而车则是策略的使用者,通过组合的方式,实现了策略与使用者之间的解耦,并且通过setter方法可以动态的更改策略,这种做法便是运用了策略模式。

参考:<<Head First设计模式>>

 

原文链接:http://www.cnblogs.com/NaLanZiYi-LinEr/p/11523304.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号