策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。
策略模式:
定义了一族算法(业务规则);
封装了每个算法;
这族的算法可互换代替(interchangeable)
组成
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
以上是百度百科提供
通过java代码来使用策略模式
动物的构成有飞行和不能飞行两种类别
要实现这个功能我们可以通过继承
继承:不灵活,对未来变更注册差
抽象方法:灵活,但每个子类都要实现一遍代码,麻烦繁琐。代码重复,没有复用代码
开发中多用组合,少用继承
组合:在类中增加一个私有域,引用另一个已有的类的实例,通过调用引用实例的方法从而获取新的功能,这种设计被称为组合(复合)
优点:组合更加灵活,改变时只需要改变实例,复用代码,更易于维护。
代码示例
飞行策略接口
public interface FlyingStrategy {
//飞行
void performFly();
}
所有的动物都要继承此类
public abstract class Animal {
//呼吸
public abstract void breathing();
//将飞行行为抽象为接口,在父类中持有该接口,并由该接口代理飞行行为
private FlyingStrategy flyingStrategy;
public void setFlyingStrategy(FlyingStrategy flyingStrategy) {
this.flyingStrategy = flyingStrategy;
}
public void fly(){
flyingStrategy.performFly();
}
}
策略家族
这里就简单的分两种能飞与不能飞
public class NoFly implements FlyingStrategy {
@Override
public void performFly() {
System.out.println("算法——不能飞行");
}
}
public class YesFly implements FlyingStrategy {
@Override
public void performFly() {
System.out.println("算法——可以飞翔!");
}
}
鸟会飞行
public class Bird extends Animal {
public Bird(){
super();
super.setFlyingStrategy(new YesFly());
}
@Override
public void breathing() {
System.out.println("我是鸟,我需要呼吸。");
}
}
狗不会飞行
public class Dog extends Animal {
public Dog(){
super();
super.setFlyingStrategy(new NoFly());
}
@Override
public void breathing() {
System.out.println("我是狗,我需要呼吸。");
}
}
测试类
public class Client {
public static void main(String[] args) {
Animal dog =new Dog();
dog.breathing();
dog.fly();
Animal bird =new Bird();
bird.breathing();
bird.fly();
}
}
策略模式中的设计模式
一、找出应用中需要变化的部分,把题目独立出来,不要和那些不需要变化的代码混在一起。
二、面向接口编程,而不是面向实现编程
三、多用组合,少用继承
步骤:
1.通过分离变化得出的策略接口
2.策略接口的实现类
3.客户程序有一个策略接口实例
4.在客户程序中选择/组装正确的策略接口实现类
策略模式的优点
1、使用了组合,是框架更加灵活
2、福有弹性,可以较好的应对变化(开一闭原则)
3、更好的代码复用性(相对于继承)
4、消除大量的条件语句
策略模式的优点
1、客户代码需要连接每个策略实现的细节
2、增加了对象的数目
策略模式的适应场景
1、许多相关的类仅仅是行为差异
2、运行时选取不同的算法变体
3、通过条件语句在多个分支中选取一