策略模式: 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
把会变化的部分取出并「封装」起来,好让其他部分不会受到影响。
思考方式:「把会变化的部分取出并封装起来,以便以后可以轻易地扩充此部分,而不影响不需要变化的其他部分」。
设计原则:针对接口编程,而不是针对实现编程。
「针对接口编程」真正的意思是「针对超类型(supertype)编程」。
这里所谓的「接口」有多个含意,接口是一个「概念」,也是一种Java的interface构造。你可以在不涉及Java interface的情况下,「针对接口编程」,关键就在多态。利用多态,程序可以针对超类型编程,执行时会根据实际状况执行到真正的行为,不会被绑死在超类型的行为上。「针对超类型编程」这句话,可以更明确地说成「变量的声明类型,应该是超类型,通常是一个抽象类或者是一个接口,如此,只要是具体实现此超类型的类所产生的对象,都可以指定给这个变量;这也意味着,声明类时,不用理会以后执行时的真正对象类型!」
设计原则:多用组合,少用继承。
使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以『在运行时动态地改变行为』,只要组合的行为对象,符合正确的接口标准即可。组合用在『许多』设计模式中。
学习实例:
实现:
Ducu.java
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public abstract void display();
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
public void swim() {
System.out.println("All ducks float, even decoys!");
}
}
接口FlyBehavior.java
public interface FlyBehavior {
public void fly();
}
实现接口fly行为类 =>
public class FlyNoWay implements FlyBehavior {
public void fly() {
System.out.println("I can't fly");
}
}
public class FlyRocketPowered implements FlyBehavior {
public void fly() {
System.out.println("I'm flying with a rocket");
}
}
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("I'm flying!!!");
}
}
接口QuackBehavior.java
public interface QuackBehavior {
public void quack();
}
实现接口Quack行为类 =>
public class MuteQuack implements QuackBehavior {
public void quack() {
System.out.println("<Silence>");
}
}
public class Quack implements QuackBehavior {
public void quack() {
System.out.println("Quack");
}
}
public class Squeak implements QuackBehavior {
public void quack() {
System.out.println("Squeak");
}
}
鸭子类=>MallardDuck.java
public class MallardDuck extends Duck {
public void display() {
System.out.println(" I'm a real Mallard duck");
}
public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyNoWay();
}
}
Ok可以测试了 => MiniDuckSimulater.java
public class MiniDuckSimulater {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
System.out.println("-----上面是改变前-------");
System.out.println("-----下面是改变后-------");
mallard.setFlyBehavior(new FlyRocketPowered());//这里可以动态改变他的fly行为
mallard.setQuackBehavior(new MuteQuack());//这里可以动态改变他的quack行为
mallard.performQuack();
mallard.performFly();
}
}
运行结果 =>
Quack
I can't fly
-----上面是改变前-------
-----下面是改变后-------
<Silence>
I'm flying with a rocket
结构图: