成功是一种观念,致富是一种义务,快乐是一种权力。
本讲内容:策略模式
一、策略模式 Strategy 介绍:
策略模式:抽象出的算法接口。以适应程序中变动的代码(策略),在Context中,只要传入具体的策略实现即可在Context中应用你提交的策略,实现你需要的功能(体现了多用组合(多个类使用),少用继承)。
即:分开变化和不会变化的部分,用一个类代表一个会变化的行为来实现接口。
二、策略模式的适用场景
1、许多相关的类仅仅是行为差异(把这些类的共性抽取为接口)
2、运行时选取不同的算法变体
3、通过条件语句在多个分支中选取一个
三、策略模式的设计原则:
是应用在千变万化中不变其架构,找出需要变化的部分将他们与不变的代码独立出来。
面向接口编程,接口为我们提供一个契约,在总体上规定了双方的行为框架,再通过多态的特性,用不同的实现类,展示了世界多样性。
组合一个策略对象,将飞行行为代理给该对象的实现。
第三个原则,即多用组合,少用继承。
策略模式的实现要点有四个:
1、通过分离变化得出的策略接口Strategy
2、各种不同的Strategy的实现类
3、超类客户程序中有一个Strategy
4、在各个客户程序中正确的组装Strategy实现类
示例一:一些鸭子有飞行能力,一些没有飞行能力,并且鸭子的飞行方式也不同(变化的)。可抽象出一个飞行接口。
1、通过分离变化得出的策略接口Strategy
/**
* 策略接口,实现鸭子的飞行行为
*
*/
public interface IFlying {
public void fly();
}
2、各种不同的 Strategy的实现类
/**
* IFlying 的实现类 即行为类(各个实现类体现了组合模式)
*/
public class FlyWithWings implements IFlying {
public void fly() {
System.out.println("我可以通过翅膀振翅高飞");
}
}
/**
* IFlying 的实现类即行为类(各个实现类体现了组合模式)
*/
public class FlyNoWay implements IFlying {
public void fly() {
System.out.println("我不会飞行!");
}
}
3、超类客户程序中有一个Strategy(加入接口的实例变量)
/*
* 超类,所有的鸭子都要继承此类
* 抽象了鸭子的行为:显示和鸣叫(这里没写)
*/
public abstract class Duck {
IFlying fly;
public Duck(){
}
/*
* 显示鸭子的外观
* 鸭子的外观各不相同,声明为abstract, 由子类实现
*/
public abstract void display();
/**
* 设置鸭子是否可以飞(可以动态改变鸭子的行为)
*/
public void setFlying(IFlying fly){
this.fly=fly;
}
/**
* 完美飞行
*/
public void performFly(){
fly.fly();//委托给行为类
}
}
4、在各个客户程序中正确的组装Strategy实现类
public class RedheadDuck extends Duck {
public RedheadDuck(){
//设置红头鸭是可以飞的
fly=new FlyWithWings();
}
public void display() {
System.out.println("我的头是红色的");
}
}
public class MallardDuck extends Duck {
public MallardDuck(){
fly=new FlyNoWay();
}
public void display() {
System.out.println("我的脖子是绿色的");
}
}
/**
*测试类
*/
public class Test {
public static void main(String[] args) {
System.out.println("测试鸭子程序");
System.out.println("************************");
Duck duck=null;
duck=new RedheadDuck();
duck.display();
duck.performFly();
duck.setFlying(new FlyNoWay());//在运行时也可以改变行为
duck.performFly();
System.out.println("************************");
System.out.println("测试完毕");
}
}
分别打印:
测试鸭子程序
************************
我的头是红色的
我可以通过翅膀振翅高飞
我不会飞行!
************************
测试完毕
策略模式的好处是代码重用和灵活变更的。譬如现在我们要添加一种用火箭方式飞行的鸭子可以轻松实现
/**
* IFlying 的实现类
*/
public class FlyWithRocket implements IFlying {
public void fly() {
System.out.println("我可以通过的火箭在太空遨游");
}
}
public class SpaceDuck extends Duck {
public SpaceDuck() {
super.setFlying(new FlyWithRocket());
}
public void display() {
System.out.println("我头戴宇航头盔");
}
}