码迷,mamicode.com
首页 > 其他好文 > 详细

【笔记】Head First 设计模式

时间:2015-03-01 11:47:19      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

设计原则
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

技术分享

设计原则
针对接口编程,而不是针对实现编程。

技术分享

问:用一个类代表一个行为,感觉似乎有点奇怪。
类不是应该代表某种“东西”吗?类不是应该同时具备
状态“与”行为吗?
答:在OO系统中,是的,类代表的东西一般都
是既有状态(实例变量)又有方法。只是在本例中,碰
巧“东西”是个行为。但是即使是行为,也仍然可以有
状态和方法,例如,飞行的行为可以具有实例变量,记
录飞行行为的属性(每秒翅膀拍动几下、最大高度和速
度等)。

问:Duck是不是也该设计成一个接口?
答:在本例中,这么做并不恰当。如你所见的,
我们已经让一切都整合妥当,而且让Duck成为一个具
体类,这样可以让衍生的特定类(例如绿头鸭)具有
Duck共同的属性和方法。我们已经 从Duck的继承结构中
删除了变化的部分,原先的问题都已经解决了,所以不
需要把Duck设计成接口。

 

测试Duck的代码
1,输入并编译下面的Duck类(Duck.java)以及两页前的
MallardDuck类(MallardDuck.java)。

public abstract class Duck {
   FlyBehavior flyBehavior;//为行为接口类型声明两个引
   QuackBehavior quackBehavior;//用变量,所有鸭子子类(在同一个zackage中)都继承它们
   public Duck() {
   } 
   
   public abstract void display();
   public void performFly() {
      flyBehavior.fly();//委托给行为类
   }
   public void performQuack() {
      quackBehavior.quack();//委托给行为类
   } 
   public void swim() {
      System.out.println(“All ducks float, even decoys!”);
   }
}

2,输入并编译FlyBehavior接口(FlyBehavior.java)与两个行为实现

类(FlyWithWings.java与FlyNoWay.java)。

public interface FlyBehavior {
   public void fly();//所有飞行行为类必须实现的接口。
}
public class FlyWithWings implements FlyBehavior {   
   public void fly() {
  System.out.println(“I’m flying!!”);//这是飞行行为的实现,给“真会”飞的鸭子用……
   }
}
public class FlyNoWay implements FlyBehavior {
   public void fly() {
       System.out.println(“I can’t fly”);//这 是 飞 行 行 为 的 实 现 ,给“不会”飞的鸭子用(包括橡皮鸭和诱饵鸭)。
   }
}

3.输入并编译QuackBehavior接口(QuackBehavior.java)及其三个实现类

(Quack.java、MuteQuack.java、Squeak.java)。

public interface QuackBehavior {
   public void quack();
}
public class Quack implements QuackBehavior {
   public void quack() {
      System.out.println(“Quack”);
   }
}
public class MuteQuack implements QuackBehavior {
   public void quack() {
  System.out.println(“<< Silence >>”);
   }
}
public class Squeak implements QuackBehavior {
   public void quack() {
  System.out.println(“Squeak”);
   }
}

4,输入并编译测试类(MiniDuckSimulator.java)

public class MiniDuckSimulator {
   public static void main(String[] args) {
      Duck mallard = new MallardDuck();
      mallard.performQuack();//这会调用MallardDuck继承来的performQuack() 方法,进而委托给该对象的QuackBehavior对象处理(也就是说,调用继承来的quackBehavior引用对象的quack())。
      mallard.performFly();
   }
}

 动态设定行为

在鸭子里建立了一堆动态的功能没有用到,就太可惜了!假设我们想在鸭子子类中通
过“设定方法(setter method)”来设定鸭子的行为,而不是在鸭子的构造器内实例化。

1,在Duck类中,加入两个新方法:

public void setFlyBehavior(FlyBehavior fb) {
    flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb) {
    quackBehavior = qb;
}

2,制造一个新的鸭子类型:模型鸭(ModelDuck.java)

public class ModelDuck extends Duck {   
    public ModelDuck() {
       flyBehavior = new FlyNoWay();//一开始,我们的模型鸭是不会飞的。
  quackBehavior = new Quack();
    }
    public void display() {
       System.out.println(“I’m a model duck”);
    }
}

3,建立一个新的FlyBehavior 类型(FlyRocketPowered.java)

public class FlyRocketPowered implements FlyBehavior {
    public void fly() {
       System.out.println(“I’m flying with a rocket!”);
       //没关系,我们建立一个利用火箭动力的飞行行为。
    }
}

4,改变测试类(MiniDuckSimulator.java),加上模型鸭,并使模型鸭具有火箭动力。

public class MiniDuckSimulator {
   public static void main(String[] args) {
      Duck mallard = new MallardDuck();
      mallard.performQuack();
      mallard.performFly();
   
          Duck model = new ModelDuck();
          model.performFly();//第一次调用performFly() 会被委托给flyBehavior对象(也就是FlyNoWay实例),该对象是在模型鸭构造器中设置的。
          model.setFlyBehavior(new FlyRocketPowered());//这会调用继承来的setter方法,把火箭动力飞行的行为设定到模型鸭中。哇!模型鸭突然具有了火箭动力飞行能力!
          model.performFly();  //如果成功了,就意味着模型鸭可以动态地改变它的飞行行为。如果把行为的实现绑死在鸭子类中,可就无法做到这样了。
   }
}

 二,观察者(Observer)模式

技术分享

【笔记】Head First 设计模式

标签:

原文地址:http://www.cnblogs.com/FH-cnblogs/p/4306747.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!