JAVA设计模式之策略模式

策略模式将可变的部分从程序中抽象分离成算法接口,在该接口下分别封装一系列算法实现,并使它们可以互相替换,从而导致客户端程序独立于算法的改变。

复合优先于继承,多用组合,少用继承

在类中增加一个私有域,引用另一个已有的类的实例,通过调用引用实例的方法从而获得新的功能,这种设计被称作组合。

组合:将飞行行为抽象为接口,在父类中持有该接口,并由该接口代替飞行行为

面向接口编程,而不是面向实现编程

多用组合,少用继承

策略模式的实现

  1. 通过分离变化得出策略接口Strategy
  2. Strategy的实现类
  3. 客户程序有一个Strategy
  4. 在客户程序中选择/组装正确的Strategy实现

策略模式优点

  1. 使用了组合,是架构更加灵活
  2. 富有弹性,可以较好的对应变化(开-闭原则)
  3. 更好的代码复用性(相对于继承)
  4. 消除大量的条件语句

策略模式缺点

  1. 客户代码需要了解每个策略实现的细节
  2. 增加了对象的数目

策略模式的适用场景

  1. 许多相关的类仅仅是行为差异
  2. 运行时选取不同的算法变体
  3. 通过条件语句在多个分支中选取一

鸭子代码实现策略模式示例

 1 /**
 2  * 超类,所有的鸭子都有继承此类
 3  * 抽象了鸭子的行为:显示和鸣叫
 4  * */
 5 public abstract class Duck {
 6 /*
 7  * 鸭子发出叫声
 8  * 通用行为,由超类实现
 9  * */
10     public void quack(){
11         System.out.println("嘎嘎。。。。");
12     }
13     /*
14      * 显示鸭子的外观
15      * 鸭子的外观各不相同,声明外abstract,由子类实现**/
16     public abstract void display();
17     
18     /** 组合:将飞行行为抽象为接口,在父类中持有该接口,并由该接口代替飞行行为*/
19     @SuppressWarnings("unused")
20     private FlyingStragety flyingStragety;
21     public void setFlyingStragety(FlyingStragety flyingStragety){
22         this.flyingStragety = flyingStragety;
23     }
24     public void fly(){
25         flyingStragety.performFly();
26     }
27 }
1.创建父类
1 /**
2  * 策略接口,实现鸭子的飞行行为
3  **/
4 public interface FlyingStragety {
5     void performFly();
6 }
2.创建飞行接口
 1 public class FlyWithRocket implements FlyingStragety{
 2     @Override
 3     public void performFly() {
 4         System.out.println("我用火箭飞行");
 5     }
 6 }
 7 public class FlyWithWin implements FlyingStragety{
 8     @Override
 9     public void performFly() {
10         System.out.println("振翅高飞");    
11     }
12 }
13 public class FlyNoWay implements FlyingStragety{
14     @Override
15     public void performFly() {
16         System.out.println("我不会飞行");    
17     }
18 }
3.实现飞行接口
 1 public class MallardDuck extends Duck{
 2     public MallardDuck(){
 3         super();
 4         super.setFlyingStragety(new FlyWithWin());
 5     }
 6     @Override
 7     public void display() {
 8         System.out.println("我的脖子是绿色的");    
 9     }
10 }
11 public class RedheadDuck extends Duck{
12 
13     public RedheadDuck(){
14         super();
15         super.setFlyingStragety(new FlyWithWin());
16     }
17     @Override
18     public void display() {
19         System.out.println("我的头是红色的");    
20     }
21 }
22 public class SpaceDuck extends Duck{
23     public SpaceDuck(){
24         super();
25         super.setFlyingStragety(new FlyWithRocket());
26     }
27     @Override
28     public void display() {
29         System.out.println("我是太空鸭子");    
30     }
31     public void quack() {
32         System.out.println("无线电通讯");
33     }
34 }
35 public class RubberDuck extends Duck{
36     public RubberDuck(){    
37         super();//调用父类的构造函数
38         super.setFlyingStragety(new FlyNoWay());
39     }
40     @Override
41     public void display() {
42         System.out.println("我的橡胶鸭子");    
43     }
44     public void quack() {
45         System.out.println("瑟瑟。。。");
46     }
47 }
48 public class BigYellowDuck extends Duck{
49     public BigYellowDuck(){
50         super();
51         super.setFlyingStragety(new FlyNoWay());
52     }
53     @Override
54     public void display() {
55         System.out.println("我是大黄鸭子");    
56     }
57     public void quack() {
58     }
59 }
4.创建子类,并决定飞行方式,及其叫声(覆盖父类方法)
 1 public class Test {
 2     public static void main(String[] args) {
 3         Duck duck =null;
 4         duck = new MallardDuck();
 5         duck.display();
 6         duck.quack();
 7         duck.fly();
 8         System.out.println("**************");
 9         duck = new RedheadDuck();
10         duck.display();
11         duck.quack();
12         duck.fly();
13         System.out.println("*****************");
14         duck = new RubberDuck();
15         duck.display();
16         duck.quack();
17         duck.fly();
18         System.out.println("*****************");
19         duck = new BigYellowDuck();
20         duck.display();
21         duck.quack();
22         duck.fly();
23         System.out.println("*****************");
24         duck = new SpaceDuck();
25         duck.display();
26         duck.quack();
27         duck.fly();
28     }
29 }
5.测试类
原文地址:https://www.cnblogs.com/wwzyy/p/4986472.html