刚买了本《HeadFirst设计模式》,开始学习这方面的内容,刚看了第一章,也就是策略模式,根据书中的思路自己整理了代码,记录如下。
策略模式: 策略模式定义了算法族,例如Fly族和Quack族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
一、Duck类及其子类
1、Duck.java
package com.sq.strategyPattern;
/**
* 鸭子基类
* @author SQ
*
*/
public abstract class Duck {
FlyBehavior flyBehavior; //声明鸭子的飞行行为接口引用
QuackBehavior quackBehavior; //声明鸭子的叫声行为接口引用
public Duck() {
}
/**
* 长相,外形
*/
public abstract void display();
/**
* 设定鸭子的飞行方式
* @param flyBehavior
*/
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
/**
* 设定鸭子的叫声
* @param quackBehavior
*/
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
/**
* 执行飞行动作
*/
public void performFly() {
flyBehavior.fly();
}
/**
* 执行叫的动作
*/
public void performQuack() {
quackBehavior.quack();
}
/**
* 游泳
*/
public void swim() {
}
}
2、MallardDuck.java
package com.sq.strategyPattern;
/**
* 绿头鸭
* @author SQ
*
*/
public class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = new Quack(); //实现绿头鸭的叫声
flyBehavior = new FlyWithWings(); //实现绿头鸭的飞行方式
}
@Override
public void display() {
System.out.println("I'm a real Mallard Duck!");
}
}
3、ModelDuck.java
package com.sq.strategyPattern;
/**
* 模型鸭子
* @author SQ
*
*/
public class ModelDuck extends Duck{
public ModelDuck() {
flyBehavior = new FlyNoWay(); //实现模型鸭子的飞行方式
quackBehavior = new Quack(); //实现模型鸭子的叫声
}
@Override
public void display() {
System.out.println("I'm a model duck!");
}
}
二、Fly算法族,用来处理飞行方式
1、接口FlyBehavior.java
package com.sq.strategyPattern;
/**
* 飞行行为接口
* @author SQ
*
*/
public interface FlyBehavior {
/**
* 飞行
*/
public void fly();
}
2、类FlyWithWings.java
package com.sq.strategyPattern;
/**
* 使用翅膀飞行
* @author SQ
*
*/
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying with wings!");
}
}
3、类FlyNoWay.java
package com.sq.strategyPattern;
/**
* 不会飞行
* @author SQ
*
*/
public class FlyNoWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("I can't fly!");
}
}
4、类FlyRocketPowered.java
package com.sq.strategyPattern;
/**
* 利用火箭飞行
* @author SQ
*
*/
public class FlyRocketPowered implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying with a rocket!");
}
}
三、Quack算法族,用于处理鸭子的叫唤
1、接口QuackBehavior.java
package com.sq.strategyPattern;
/**
* 叫唤行为接口
* @author SQ
*
*/
public interface QuackBehavior {
/**
* 叫唤
*/
public void quack();
}
2、类Quack.java
package com.sq.strategyPattern;
/**
* 鸭子叫
* @author SQ
*
*/
public class Quack implements QuackBehavior {
@Override
public void quack() {
System.out.println("Quack!");
}
}
3、类MuteQuack.java
package com.sq.strategyPattern;
/**
* 不会叫唤
* @author SQ
*
*/
public class MuteQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("<< Silence >>");
}
}
4、类Squeak.java
package com.sq.strategyPattern;
/**
* 叽叽叫
* @author SQ
*
*/
public class Squeak implements QuackBehavior {
@Override
public void quack() {
System.out.println("Squeak!");
}
}
四、编译测试类
package com.sq.strategyPattern;
/**
* 策略模式(StrategyPattern) 的 编译测试类
* @author SQ
*
*/
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallard = new MallardDuck(); //实例化一个绿头鸭mallard
mallard.performFly(); //mallard如何飞
mallard.performQuack(); //mallard如何叫唤
mallard.display(); //mallard表明自己的身份
Duck modelDuck = new ModelDuck(); //实例化一个模型鸭子modelDuck
modelDuck.performFly(); //modelDuck如何飞
modelDuck.setFlyBehavior(new FlyRocketPowered()); //改变modelDuck飞行方式
modelDuck.performFly(); //modelDuck如何飞
}
}
五、输出结果
I'm flying with wings!
Quack!
I'm a real Mallard Duck!
I can't fly!
I'm flying with a rocket!
六、总结
在这里除了策略模式外我还学到了几种设计原则:
1、找出应用中可能需要改变之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
2、针对接口编程,而不是针对实现编程。具体指针对超类型编程,即利用多态。
3、多用组合,少用继承。即多用HAS-A(有一个),少用IS-A(是一个)。