策略模式(参考仿造《Head First设计模式》)
2016-05-21 13:46
453 查看
刚刚开始学习,使用一个书里简单的小例子帮助记忆。
策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
输出:
这样全面解耦以后,可以起无数个子类来继承主类,只要每个子类内部实例化各个接口方法即可。例如做饭的接口,购买的接口等等,主类只要再起几个代理方法,子类构造方法实例化这些接口即可。
2、叫声行为接口
2、可以飞
3、嘎嘎叫
4、吱吱叫
如果有新的鸭子,比如一个模型鸭子,不会叫也不会飞,这个时候只要再写一个类即可。
控制台输出:
这样,如果又有新的鸭子,新的方法(比如出生地,模型鸭子没有,则父类Duck再代理一个出生地方法)再生成别的类即可,不影响现有的方法
策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
我们先来看一个简单的案例
主类
//完全解耦,只关联了接口,没有任何实例化,靠子类去实现 public class Food { public Eat eatBehavior; //接口 public void performEat(){ //代理实现接口,测试的时候直接调用该方法即可 eatBehavior.eat(); } }
子类
public class Noodle extends Food { public Noodle(){ eatBehavior = new Noodle_imp(); //实例化接口 } }
接口
public interface Eat { void eat(); }
实例化接口
public class Noodle_imp implements Eat { @Override public void eat() { System.out.println("吃面条"); } }
测试
public static void main(String[] args) { Food f = new Noodle(); //使用多态,noodle子类中有构造方法实例化接口方法 f.performEat(); //调用父类方法,此时已经实例化接口方法 }
输出:
吃面条
这样全面解耦以后,可以起无数个子类来继承主类,只要每个子类内部实例化各个接口方法即可。例如做饭的接口,购买的接口等等,主类只要再起几个代理方法,子类构造方法实例化这些接口即可。
下面就是headFirst里面的一个案例,比较全面,复制到项目里面跑一下就知道精妙之处了。
一、主类
public class Duck { public FlyBehavior flyBehavior;//飞行行为 public QuackBehavior quackBehavior;//叫声行为 public void swim(){ System.out.println("我会游泳"); } public void display(){ System.out.println("我是白色的"); } public void performQuack(){//叫声代理方法 quackBehavior.quack(); } public void performFly(){//飞行代理方法 flyBehavior.fly(); } public void setFlyBehavior(FlyBehavior flyBehavior) {//项目中可以动态修改飞行 this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } }
二、行为接口
1、飞行行为接口public interface FlyBehavior{ void fly(); }
2、叫声行为接口
public interface QuackBehavior { void quack(); }
三、行为实现
1、不能飞public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("不能飞"); } }
2、可以飞
public class FlyWithings implements FlyBehavior { @Override public void fly() { System.out.println("飞行"); } }
3、嘎嘎叫
public class Quack implements QuackBehavior{ @Override public void quack() { System.out.println("嘎嘎叫"); } }
4、吱吱叫
public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("吱吱叫"); } }
四、子类
public class MalardDuck extends Duck{ public MalardDuck(){ quackBehavior = new Quack();//使用多态,实例化一个“嘎嘎叫”的鸭子 flyBehavior = new FlyWithings();//不会飞 } @Override public void display() { System.out.println("我是绿色的"); } }
五、测试
public class test { public static void main(String[] args) { Duck d = new MalardDuck(); d.performQuack(); d.performFly(); d.swim(); d.display(); } }
如果有新的鸭子,比如一个模型鸭子,不会叫也不会飞,这个时候只要再写一个类即可。
为了能动态生成模型鸭子,在Duck父类里面加入了set方法
//实现的时候 public class test { public static void main(String[] args) { /*Duck d = new MalardDuck(); d.performQuack(); d.performFly(); d.swim(); d.display();*/ Duck d = new ModelDuck();//模型鸭子 d.performQuack(); d.swim(); d.display(); d.setFlyBehavior(new FlyRocketPowered());//飞行模式,需要一个实现接口的方法,该类实现了fly接口的方法 d.performFly(); } }
控制台输出:
嘎嘎叫 我会游泳 我是模型鸭 我能使用火箭飞行
这样,如果又有新的鸭子,新的方法(比如出生地,模型鸭子没有,则父类Duck再代理一个出生地方法)再生成别的类即可,不影响现有的方法
相关文章推荐
- ExtJs框架 文件上传
- linux基础编程 多线程中的互斥锁 pthread_mutex_lock
- 只有五行的算法--Floyd--Warshall
- 关于input style属性兼容性问题
- 堆--神奇的优先队列
- NetAnalyzer笔记 目录
- ubuntu下用postfix搭建邮件服务器
- 安卓应用底部菜单栏+fragment
- 数据密集型系统架构设计
- 《Linux命令行与shell脚本》笔记--第1章:初识linux shell
- 第一个独立的小岛数
- tomcat6 中context配置,使用tomcat 数据源
- 阿里动态化解决方案Weex分享
- Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送
- Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送
- 《浪潮之巅》读书笔记
- 阿里巴巴Druid数据源的配置与使用
- Delphi读写UTF-8、Unicode格式文本文件
- 城市最短路径
- 百度富文本编辑器的使用