HeadFirst 设计模式学习笔记1--策略模式

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。

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(); } 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(); } }

 

示例代码下载

你可能感兴趣的:(设计模式,编程,String,Class,interface,setter)