1.策略模式:
将可变的部分从程序中抽象分离成算法接口,在该接口下分别封装一系列算法实现。
并使他们可以相互替换,
从而导致客户端程序独立于算法的改变。
2.使用策略模式的思想是——多用组合,少用继承
什么是组合?
—在类中增加一个私有域,引用另一个已有的类的实例,通过调用引用的实例的方法,,从而获得新的功能,这种设计被称作composition(组合、复合)。
3.策略模式的优点
(1)、策略模式因为使用了组合,使得架构更加灵活
(2)、富有弹性,可以较好的应对变化(开闭原则)
(3)、更好的代码复用性(相对于继承)
(4)、消除大量的条件语句 (比如 if ,else)
4.
4.策略模式的使用场景
(1)许多相关的类仅仅是行为差异
(2)运行时选取不同的算法变体
(3)通过条件语句在多个分支中选取之一
案例:
假设现在有一个鸭子抽象类Duck , 它们都会飞,但是飞的方式不一样(有的用翅膀,有的用火箭,有的不会飞) 。使用策略模式让设计更灵活
首先,我们定义一个飞行的接口
/*
* 策略接口,实现鸭子的飞行行为
*/
public interface FlyingStragety {
void performFly();
}
* 策略接口,实现鸭子的飞行行为
*/
public interface FlyingStragety {
void performFly();
}
接下来,定义一个鸭子抽象类, 在该类中,需要有一个私有的飞行接口的应用,使鸭子能够使用这个接口来实现飞行 。
/*
* 超类,所有的鸭子都要继承此类
* 抽象了鸭子的行为:显示和鸣叫
*/
public abstract class Duck {
/*
* 鸭子发出叫声
* 通用行为,由超类实现
*/
public void quack(){
System.out.println("嘎嘎嘎");
}
/*
* 显示鸭子的外观
* 鸭子的外观各不相同,声明为abstract, 由子类实现
*/
public abstract void display();
private FlyingStragety flyingStragety;
public void setFlyingStragety(FlyingStragety flyingStragety) {
this.flyingStragety = flyingStragety;
}
public void fly(){
flyingStragety.performFly();
}
}
]
* 超类,所有的鸭子都要继承此类
* 抽象了鸭子的行为:显示和鸣叫
*/
public abstract class Duck {
/*
* 鸭子发出叫声
* 通用行为,由超类实现
*/
public void quack(){
System.out.println("嘎嘎嘎");
}
/*
* 显示鸭子的外观
* 鸭子的外观各不相同,声明为abstract, 由子类实现
*/
public abstract void display();
private FlyingStragety flyingStragety;
public void setFlyingStragety(FlyingStragety flyingStragety) {
this.flyingStragety = flyingStragety;
}
public void fly(){
flyingStragety.performFly();
}
}
]
接下来的问题就变成创建一个实现飞行接口的实例,给鸭子。
定义一个用用翅膀飞的飞行接口实现类
public class FlyWithWin implements FlyingStragety {
public void performFly() {
System.out.println("用翅膀飞");
}
}
public void performFly() {
System.out.println("用翅膀飞");
}
}
创建一个用翅膀飞的鸭子的类,继承自抽象鸭子类 Duck
public class MallardDuck extends Duck {
public MallardDuck(){
super();
super.setFlyingStragety(new FlyWithWin());
}
@Override
public void display() {
System.out.println("我的脖子是绿色的");
}
}
public MallardDuck(){
super();
super.setFlyingStragety(new FlyWithWin());
}
@Override
public void display() {
System.out.println("我的脖子是绿色的");
}
}
测试
public class DuckTest {
public static void main(String[] args){
Duck duck =null;
duck = new MallardDuck();
duck.display();
duck.quack();
duck.fly();
System.out.println("测试完毕");
}
}
public static void main(String[] args){
Duck duck =null;
duck = new MallardDuck();
duck.display();
duck.quack();
duck.fly();
System.out.println("测试完毕");
}
}
输出结果
我的脖子是绿色的
嘎嘎嘎
用翅膀飞
测试完毕
嘎嘎嘎
用翅膀飞
测试完毕
如果是用火箭飞,只需创建一个新的 实现飞行接口的类,然后在鸭子的构造器中使用
super.setFlyingStragety()传入即可