定义:将可变的部分从程序中抽象分离成算法接口,在该接口下分别封装一系列算法实现,并使他们可以相互替换,从而导致客户端独立于算法的改变。
组合:
在类中增加一个私有域,引用另一个已有的类的实例,通过调用引用实例的方法从而获得新的功能,这种设计被称作组合(复合)。
策略模式中的设计原则
1、找出应用中需要变化的部分,把他们独立出来,不要和那些不需要变化的代码混在一起。
2、面向接口编程,而不是面向实现编程。
3、多用组合,少用继承
策略模式的实现
1、通过分离变化得出的策略接口Strategy
2、Strategy的实现类
3、客户程序"有一个"Strategy
4、在客户程序中选择/组装正确的Strategy实现
策略模式的优点:
1、使用了组合,使架构更加灵活
2、富有弹性,可以较好的应对变化(开一闭原则)
3、更好的代码复用性(相对于继承)
4、消除大量的条件语句
策略模式的缺点
1、客户代码需要了解每个策略实现的细节
2、增加了对象的数目
策略模式的适用场景
1、许多相关的类仅仅是行为差异
2、运行时选取不同的算法变体
3、通过条件语句在多个分支中选取一
package com.practice;
import com.practice.impl.FlyNoWay;
public class BigYellow extends Duck {
public BigYellow(){
super();
super.setFlyingStragety(new FlyNoWay());
}
@Override
public void display() {
System.out.println("我身体很大,全身黄色");
}
public void quack(){
System.out.println("我不会叫");
}
}
package com.practice;
/*
* 超类,所有鸭子都要继承此类
* 抽象了鸭子的行为:显示和鸣叫
*/
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();
}
}
package com.practice;
public class DuckTest {
public static void main(String[] args) {
System.out.println("测试鸭子程序");
System.out.println("--------------");
Duck duck = null;
// duck = new MallardDuck();
// duck = new RedheadDuck();
// duck = new RubberDuck();
// duck = new BigYellow();
duck = new SpaceDuck();
duck.display();
duck.quack();
duck.fly();
System.out.println("--------------");
System.out.println("测试完毕");
}
}
package com.practice;
/*
* 策略接口,实现鸭子的飞行行为
*/
public interface FlyingStragety {
void performFly();
}
package com.practice;
import com.practice.impl.FlyWithWin;
public class MallardDuck extends Duck {
public MallardDuck(){
super();
super.setFlyingStragety(new FlyWithWin());
}
@Override
public void display() {
System.out.println("我的脖子是绿色的");
}
}
package com.practice;
import com.practice.impl.FlyWithWin;
public class RedheadDuck extends Duck {
public RedheadDuck(){
super();
super.setFlyingStragety(new FlyWithWin());
}
@Override
public void display() {
System.out.println("我的头是红色的");
}
}
package com.practice;
import com.practice.impl.FlyNoWay;
public class RubberDuck extends Duck {
public RubberDuck(){
super();
super.setFlyingStragety(new FlyNoWay());
}
@Override
public void display() {
System.out.println("我全身发黄,嘴巴很红");
}
public void quack(){
System.out.println("嘎~嘎~嘎~嘎~");
}
}
package com.practice;
import com.practice.impl.FlyWithRoket;
public class SpaceDuck extends Duck {
public SpaceDuck(){
super();
super.setFlyingStragety(new FlyWithRoket());
}
@Override
public void display() {
System.out.println("我头戴宇航头盔");
}
public void quack(){
System.out.println("我通过无线电与你通信");
}
}
package com.practice.impl;
import com.practice.FlyingStragety;
public class FlyNoWay implements FlyingStragety {
@Override
public void performFly() {
System.out.println("我不会飞行");
}
}
package com.practice.impl;
import com.practice.FlyingStragety;
public class FlyWithRoket implements FlyingStragety {
@Override
public void performFly() {
System.out.println("用火箭在太空遨游");
}
}
package com.practice.impl;
import com.practice.FlyingStragety;
public class FlyWithWin implements FlyingStragety {
@Override
public void performFly() {
System.out.println("振翅高飞");
}
}