软件开发的一个不变的真理---CHANGE
拥抱变化,为变化而生!
设计原则
找出可能发生变化的地方,把它们独立出来单独处理,不要和那些变化的代码混在一起!
把会变化的部分抽取并进行“封装”,以后可以轻松的改动或扩展此部分,而不影响其它不需要变化的部分!
设计原则
针对接口编程,而不是针对实现编程!
针对接口编程,真正的意思是“针对超类型编程”
抽象类、接口
抽象类持有接口的引用
继承
运行时可以动态为子类继承下来的接口指定具体实现类
设计原则
多用组合,少用继承!
将多个类结合起来使用(1个类持有其它类的引用),就是组合(composition)!
这里的其它类便是一组行为(一族算法)的封装
策略模式
定义了算法族,分别封装起来,并让它们可以相互替换。
此模式让算法的变化独立于使用算法的客户。
=======================================================================
不同类型的鸭子和它们的行为
鸭子的父类
package duck; import duck.fly.FlyBehavior; import duck.quack.QuackBehavior; public abstract class Duck { public Duck() { } /** * 共同的行为,在父类中定义即可 */ public void swim() { System.out.println("All duck float!"); } /** * 不同子类的display行为不同,只能让子类去实现 */ public abstract void display(); //============================== FlyBehavior flyBehavior;//接口,为多态提供了前提 QuackBehavior quackBehavior;//接口,为多态提供了前提 /** * 委托行为到父类中,这里是关键! */ public void performFly() { flyBehavior.fly(); } public void perfomQuack() { quackBehavior.quack(); } /** * 对外部暴露修改实现类的入口 * @param flyBehavior */ public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } }
具体鸭子---野鸭
package duck; import duck.fly.impl.FlyWithSwing; import duck.quack.impl.Quack; public class MallardDuck extends Duck { public MallardDuck() { //对继承下来的属性进行默认初始化 init(); } private void init() { flyBehavior = new FlyWithSwing(); quackBehavior = new Quack(); } public void display() { System.out.println("I'm a real Mallard Duck"); } }
具体鸭子---模型鸭
package duck; import duck.fly.impl.FlyWithSwing; import duck.quack.impl.MuteQuack; public class ModelDuck extends Duck { public ModelDuck() { //对继承下来的属性进行初始化 init(); } private void init() { flyBehavior = new FlyWithSwing(); quackBehavior = new MuteQuack(); } @Override public void display() { System.out.println("I'm a model duck"); } }
鸭子飞的行为
package duck.fly; public interface FlyBehavior { void fly(); }
飞的行为(一)
package duck.fly.impl; import duck.fly.FlyBehavior; public class FlyWithSwing implements FlyBehavior { /** * 专门针对接口进行实现 * 让特定的行为脱离主线,独立出来,需要新的行为,只需要对外部进行改变即可 */ @Override public void fly() { System.out.println("fly with swing"); } }
飞的行为(二)
package duck.fly.impl; import duck.fly.FlyBehavior; public class FlyNoWay implements FlyBehavior { /** * 由行为类去实现接口,而不是让每个子类单独实现一次,提高了代码复用性 * 需要的地方直接引用这个行为类的超类接口即可---解耦,可以灵活改变行为 */ @Override public void fly() { System.out.println("fly no way"); } }
飞的行为(三)
package duck.fly.impl; import duck.fly.FlyBehavior; public class FlyRocketPower implements FlyBehavior { @Override public void fly() { System.out.println("I'm flying with a rocket!"); } }
鸭子叫的行为
package duck.quack; public interface QuackBehavior { void quack(); }
叫的行为(一)
package duck.quack.impl; import duck.quack.QuackBehavior; public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("quack"); } }
叫的行为(二)
package duck.quack.impl; import duck.quack.QuackBehavior; public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("squeak"); } }
叫的行为(三)
package duck.quack.impl; import duck.quack.QuackBehavior; public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("<< Silence >>"); } }
测试
package test; import duck.Duck; import duck.MallardDuck; import duck.ModelDuck; import duck.fly.impl.FlyRocketPower; import duck.quack.impl.Squeak; public class DuckTest { public static void main(String[] args) { Duck mallard = new MallardDuck(); mallard.swim(); mallard.display(); mallard.performFly(); mallard.perfomQuack(); System.out.println("=======break line======="); Duck model = new ModelDuck(); model.swim(); model.display(); model.performFly(); //动态修改行为 model.setFlyBehavior(new FlyRocketPower()); model.performFly(); model.perfomQuack(); //动态修改行为 model.setQuackBehavior(new Squeak()); model.perfomQuack(); } }
另一个使用策略模式的例子
相关推荐
策略模式: 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes ...
NULL 博文链接:https://jacky-dai.iteye.com/blog/1132058
《HeadFirst设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式。前言先介绍这本书的用法;第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、...
策略模式 共享模式词汇的威力 我如何使用设计模式? 设计箱内的工具 习题解答 2 让你的对象知悉现况 气象观测站 认识观察者模式 出版者+订阅者=观罕者模式 五分钟短剧:观察主题 定义观察者模式 松...
Head First 设计模式 策略模式案例,鸭子案例的具体代码。 里面分四个package 第一个package是最原始的demo 第二个package在鸭子类添加了fly方法 第三个package 通过抽象接口 第四个package 使用策略模式
head-first-design-pattern源码,第一章strategy-pattern(策略模式),融入了自己的见解,有一些错误的实现,也有一些标准答案,对照着看更能理解模式的精髓。
动态控制Page页的Head信息 SubmitOncePage:解决刷新页面造成的数据重复提交问题 SharpRewriter:javascript + xml技术利用#实现url重定向 采用XHTML和CSS设计可重用可换肤的WEB站点 asp.net的网址重定向方法的比较...
##1.Strategy(策略模式) 策略设计模式就是定义算法族(接口中定义的方法<也就是对象的行为>),分别进行封装(接口实现类),让他们之间可以相互替换(通过组合的方式绑定到调用对象上),以此来达到算法的变化...
design_patterns(设计模式)Design Patterns In PythonDesign Patterns Introduction(设计模式介绍)Strategy Pattern(策略模式)实现:design_patterns/strategy.py示例:examples/strategy_example.pyObserver ...
该代码基于 Head First Design Patterns 一书中的相应示例。待办事项 使隐式控制器的视图依赖显式。 添加 JavaFX 视图并使用现有控制器和模型。 为控制器和模型编写单元测试。 尝试将观察者组合成一个观察者,通过 ...