设计模式--策略模式
Posted dxj1016
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式--策略模式相关的知识,希望对你有一定的参考价值。
设计模式分为三种类型,共23种
- 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式。
- 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
- 行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)。
创建型模式主要用于创建对象
结构型模式主要用于处理类或对象的组合
行为型模式主要用于描述类或对象如何交互和怎样分配职责
1、基本介绍
- 策略模式(Strategy Pattern)中,定义算法族,分别封装起来,让他们之间可以
互相替换,此模式让算法的变化独立于使用算法的客户。 - 这算法体现了几个设计原则:
- 第一、把变化的代码从不变的代码中分离出来;
- 第二、针对接口编程而不是具体类(定义了策略接口);
- 第三、多用组合/聚合,少用继承(客户通过组合方式使用策略)。
2、例子分析
- 其它鸭子,都继承了Duck类,所以fly让所有子类都会飞了,这是不正确的
- 上面说的1 的问题,其实是继承带来的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。会有溢出效
- 为了改进1问题,我们可以通过覆盖fly 方法来解决 => 覆盖解决
- 问题又来了,如果我们有一个玩具鸭子ToyDuck, 这样就需要ToyDuck去覆盖Duck
的所有实现的方法 => 解决思路 策略模式 (strategy pattern)
3、例子代码
思路分析
策略模式: 分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为的变化独立于算法的使用者
超类:
package designpattern.strategy.improve1;
public abstract class Duck {
//为行为接口类型声明两个引用变量
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public abstract void display();//显示鸭子信息
public void performFly() {
flyBehavior.fly();//委托给行为类
}
public void performQuack() {
quackBehavior.quack();//委托给行为类
}
public void swim() {
System.out.println("鸭子会游泳~~");
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
会变动的行为接口–飞行行为
package designpattern.strategy.improve1;
//所有飞行行为类必须实现的接口
public interface FlyBehavior {
void fly(); // 子类具体实现
}
两个类实现飞行接口
package designpattern.strategy.improve1;
//这是飞行行为的实现,给不会飞的鸭子用
public class FlyNoWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("这是不会飞的鸭子");
}
}
package designpattern.strategy.improve1;
//这是飞行行为的实现,给会飞的鸭子用
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("这是真的会飞的鸭子");
}
}
会变动的行为接口–叫声行为
package designpattern.strategy.improve1;
//所有叫的行为类必须实现的接口
public interface QuackBehavior {
public void quack();
}
三个类实现叫声行为
package designpattern.strategy.improve1;
public class QuackNoWay implements QuackBehavior {
@Override
public void quack() {
System.out.println("这是不会叫的鸭子");
}
}
package designpattern.strategy.improve1;
public class QuackWithGuaGua implements QuackBehavior{
@Override
public void quack() {
System.out.println("呱呱叫");
}
}
package designpattern.strategy.improve1;
public class QuackWithZhiZhi implements QuackBehavior {
@Override
public void quack() {
System.out.println("吱吱叫");
}
}
实现鸭子的类
package designpattern.strategy.improve1;
public class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = new QuackWithGuaGua();
flyBehavior = new FlyWithWings();
}
@Override
public void display() {
System.out.println("display");
}
}
测试类
package designpattern.strategy.improve1;
public class Client {
public static void main(String[] args) {
Duck duck = new MallardDuck();
duck.performFly();
duck.performQuack();
}
}
/*
这是真的会飞的鸭子
呱呱叫
*/
在duck中的两个set方法没用上,可以调用这两个set方法改变鸭子的行为
再创建一个模型鸭子来继承超类,这个模型鸭子不会飞也不会叫:
package designpattern.strategy.improve1;
public class ModelDuck extends Duck {
public ModelDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new QuackNoWay();
}
@Override
public void display() {
System.out.println("这是一个不会飞不会叫的鸭子");
}
}
再写一个会利用火箭来飞的飞行行为
package designpattern.strategy.improve1;
public class FlyRocket implements FlyBehavior {
@Override
public void fly() {
System.out.println("这个是利用火箭动力的飞行行为");
}
}
重新写测试类
package designpattern.strategy.improve1;
public class Client {
public static void main(String[] args) {
Duck duck = new MallardDuck();
duck.performFly();
duck.performQuack();
Duck duck1 = new ModelDuck();
duck1.performFly();//改变前是不会飞的
duck1.setFlyBehavior(new FlyRocket());//在运行时改变了飞行行为
duck1.performFly();//改变后为火箭飞行
}
}
/*
这是真的会飞的鸭子
呱呱叫
这是不会飞的鸭子
这个是利用火箭动力的飞行行为
*/
在运行时想要修改鸭子的行为,只需要调用鸭子的setter方法即可;如要添加新的行为,只需要加个类然后实现飞行行为或者叫声行为,然后可以在客户端调用setter方法动态改变行为
以上是关于设计模式--策略模式的主要内容,如果未能解决你的问题,请参考以下文章