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 interfaceFlyBehavior{
-
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 interfaceQuackBehavior{
-
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();
}
}
分享到:
相关推荐
http://blog.csdn.net/laszloyu/archive/2010/05/11/5579765.aspx 示例代码
HeadFirst 设计模式学习笔记3--装饰模式 Demo http://blog.csdn.net/laszloyu/archive/2010/05/12/5582561.aspx
HeadFirst 设计模式学习笔记2--观察者模式 demo http://blog.csdn.net/laszloyu/archive/2010/05/12/5581769.aspx
HeadFirst设计模式学习笔记比较全面详细地讲解了13个设计模式,有利于大家更好的学习HeadFirst设计模式,希望亲们会喜欢~~~
Head First 设计模式学习笔记。更多内容请参见文章内容。
Head.First 设计模式学习笔记.pdf Head.First 设计模式学习笔记.pdf
著名的《Head First Design Pattern》学习笔记,摘要这本书中的设计思路。由于书本过长,整理出笔记帮助回想起设计模式。文件是docx格式,只能由OFFICE Word 2007之后的版本打开,内附Visio类图文件。本文由个人整理...
NULL 博文链接:https://chxiaowu.iteye.com/blog/1276845
设计模式Head First学习笔记,以及使用java编写的设计模式源码,Java原生sdk实现23种设计模式
学习设计模式时,做的笔记,主要参考了《Head First设计模式》
最近在设计模式的一些内容,主要的参考书籍是《Head First 设计模式》,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了帮助我更深入地理解设计模式,二...
近在学设计模式的一些内容,主要的参考书籍是《Head First 设计模式》,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了帮助我更深入地理解设计模式,二...
VS2005 ASP.NET本地化学习笔记&感受 在自定义Server Control中捆绑JS文件 Step by Step 深度解析Asp.Net2.0中的Callback机制 使用 Web 标准生成 ASP.NET 2.0 Web 站点 ASP.NET 2.0基于SQLSERVER 2005的aspnetdb.mdf...
Head First学习笔记+Head First之装饰者模式高清PDF
设计模式、设计模式 可复用面向对象软件的基础,实现了 Gof 的 23 种设计模式。 内容包括三大原则(继承、封装、多态)、类图、设计原则。 数据库 :floppy_disk: 参考 数据库系统原理。 参考 SQL 必知必会。 ...
学习笔记都在这里了 好好学习,天天向上!生命不息,阅读不止! 本仓库参考以下书籍或资料 JavaScript高级程序设计(第三版) You don't know JS 系列 ES6 标准入门 Node.JS深入浅出 图解HTTP HTTP权威指南 Head First...