博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【HeadFirst 设计模式总结】1.策略模式
阅读量:5984 次
发布时间:2019-06-20

本文共 4407 字,大约阅读时间需要 14 分钟。

1.书中举了一个鸭子类的设计,有些会飞或者会叫,有些不会飞可能也不会叫,用继承则导致不该有的功能通过继承而继承了下来,使用接口则代码无法做到最大程度的重用。进而引出设计原则1:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起,把会变化的部分取出并封装起来,好让其他部分不会受到影响。——每个设计模式背后的精神所在。

2.我们希望运行时动态的改变一些行为,这就引出了第二个原则:针对接口编程,而不是针对实现编程。 因此,鸭子的行为将被放在分开的类——我们可以将其叫做“行为类”中,此类专门提供某行为接口的实现。针对接口编程的意思是针对超类型编程——变量的声明类型应该是超类,通常是一个抽象类或者一个接口,如此,只要是具体实现此超类型的类所产生的对象,都可以指定给这个变量,这也意味着,声明类时不用理会以后执行时的真正对象类型。

针对实现编程 

Dog d=new Dog(); 

d.dark(); 
针对接口编程 

Animal animal=new Dog(); 

animal.makesound(); 
更好的针对接口编程

a = getAnimal(); 

a.makeSound();

不得不针对具体实现coding 

利用animal多态处理 
运行时才指定具体实现的对象

最后设计的样子是两个接口,一个飞,一个叫,每个接口中有相应的方法,然后设计不同的类对这个接口进行不同的实现。

然后在超类的设计中,行为变量被声明为“接口”类型的变量,然后具体动作的方法由接口类型的变量相对应的方法所实现。子类中,构造函数中指明这些接口类型的变量具体对应的是哪一个具体实现。这样的话,通过一个“接口”类型的变量,灵活性就更高了,虽然此时在构造函数中我们还是引入了具体实现。

3.进一步,我们希望可以自己设定具体的行为而不是在构造函数中写死,那么我们可以使用setter method,通过向外提供接口来设置从超类那继承的接口类型的成员变量。

4.最后我们看到的设计局面是:各种鸭子继承了Duck,飞行行为实现了FlyBehavior接口,呱呱叫行为实现了QuackBehavior接口。设计的基本理念在于行为不是继承而来的,而是通过适当的行为对象“组合”而来。这个总结就可以归纳出第三个设计原则:多用组合,少用继承。这样可使系统更具有弹性。

最后我们来看看这个模式的定义:

策略模式定义了算法簇,分别封装起来,让它们之间可以互相替换,此模式让方法的变化独立于使用方法的Client,适用于继承后的动作发生变化,要动态的改变对象的行为时。

核心思想:将is-a 转换为has-a.

 

 

基本的思路:将一些原先要继承的方法,以接口的方式抽象出来,然后再以实现该接口的方式定义一些类以完成实际能力的实现;同时在基类中以组合的方式将该接口的实例放入基类,基类同时提供设置这个实例的接口以及这个方法的封装,子类继承基类时对这些接口实例进行设置即可。

 

5.TIPs:

1)在开发中使用模式词汇,但是不要写一个helloworld都要扯上模式。

2)没有所谓设计模式库,只有设计模式条目。

3)模式并不只是利用了OO的设计原则。应用场景中若是没有合适的模式则使用最基本的OO原则。

附:鸭子的设计

建立不同的鸭子类 fly行为//  飞行接口 public interface FlyBehavior {  public void fly();  }  //  飞 public class FlyWithWings implements FlyBehavior{  public void fly() {          System.out.println("正在用翅膀飞行");      }  }  //  不飞 public class FlyNoWay implements FlyBehavior{  public void fly() {          System.out.println("不会飞");      }  }  //坐火箭飞 public class FlyRocketPowered implements FlyBehavior{  public void fly() {          System.out.println("坐火箭飞");      }  }  quack行为//  叫接口 public interface QuackBehavior {  public void quack();  }  // 嘎嘎叫 public class Quack implements QuackBehavior. {  public void quack() {          System.out.println("嘎嘎叫");      }  }  //  吱吱叫 public class Squeak implements QuackBehavior{  public void quack() {          System.out.println("吱吱叫");      }  }  //  不叫 public class MuteQuack implements QuackBehavior{  public void quack() {          System.out.println("不会叫");      }  } 实现Duck类  //  鸭子超类public abstract class Duck {  //  默认的行为 FlyBehavior flyBehavior;      QuackBehavior quackBehavior;  public Duck() {      }  public void setFlyBehavior(FlyBehavior. fb) {          flyBehavior = fb;      }  public void setQuackBehavior(QuackBehavior. qb) {          quackBehavior = qb;      }  abstract void display();  public void performFly() {          flyBehavior.fly();      }  public void performQuack() {          quackBehavior.quack();      }  public void swim() {          System.out.println("正在游泳~~");      }  }  //  野鸭       public class MallardDuck extends Duck {       public MallardDuck() {           quackBehavior = new Quack();                   flyBehavior = new FlyWithWings();  //这里也可以使用setFlyBehavior方法,下同!     }       public void display() {           System.out.println("绿头鸭");       }  }       //  红头鸭       public class RedHeadDuck extends Duck {       public RedHeadDuck() {           flyBehavior = new FlyWithWings();           quackBehavior = new Quack();       }       public void display() {           System.out.println("红头鸭");       }  }       //  橡皮鸭      public class RubberDuck extends Duck {       public RubberDuck() {           flyBehavior = new FlyNoWay();           quackBehavior = new Squeak();       }       public void display() {           System.out.println("橡皮鸭");       }  }       //模型鸭  public class ModelDuck extends Duck {       public ModelDuck() {           flyBehavior = new FlyNoWay();           quackBehavior = new Quack();       }       public void display() {           System.out.println("模型鸭");       }  }  测试代码:public class MiniDuckSimulator {  public static void main(String[] args) {          MallardDuck    mallard = new MallardDuck();          RubberDuck    rubberDuckie = new RubberDuck();          RedHeadDuck    redHeadDuck = new RedHeadDuck();          ModelDuck    model = new ModelDuck();          mallard.performQuack();          rubberDuckie.performQuack();          redHeadDuck.performQuack();          model.performFly();              model.setFlyBehavior(new FlyRocketPowered());          model.performFly();      }  }

转载于:https://www.cnblogs.com/shakin/p/4218503.html

你可能感兴趣的文章
linux 安装jdk
查看>>
Gradle 1.12用户指南翻译——第六十一章. Gradle包装器
查看>>
Silverlight(HTC手机的日期效果)日历控件源代码下载
查看>>
学生机房虚拟化(五)深入配置宿主系统2
查看>>
结合django动态生成salt的pillar数据
查看>>
Vmvare 虚拟机挂载 移动硬盘和分区
查看>>
Scrapy结合Mysql爬取天气预报入库
查看>>
基于角色的访问控制,Docker EE 为 Kubernetes 护航
查看>>
Android ContentObserver
查看>>
Windows Live Writer 的代码高亮插件
查看>>
用log4j将日志写入数据库
查看>>
pandas.DataFrame.reset_index
查看>>
nagios报错:./stdio.h:456:1: error: 'gets' undeclared here (not in a function)
查看>>
【java】java反射初探 ——“当类也学会照镜子”
查看>>
RMI原理一记远程调用
查看>>
“云”里必需品还有什么?
查看>>
技术分享连载(四十四)
查看>>
F5忘记ROOT\ADMIN密码怎么办
查看>>
【编译打包】coreseek-3.2.14-2.el6.src.rpm
查看>>
测试一下H2数据库的性能
查看>>