一.设计模式入门
设计模式是人们在面对同类型软件工程设计问题所总结出的一些有用经验。模式不是代码,而是某类问题的通用设计解决方案。
4人组Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides总结写了《设计模式》。
设计模式的优点和用途。
学习设计模式最好的方式:在你的设计和以往的工程里寻找何处可以使用它们。
设计模式的本质目的是使软件工程在维护性、扩展性、变化性、复杂度方面成O(N)。
OO是基础原则,设计模式是具体方法、工具。
在java里IO流的类设计,为什么把BufferedReader设计成:
new BufferedReader(new FileReader("F:\test.java"));
而不是设计成:BufferedReader extends FileReader;然后new BufferedReader("F:\test.java");
按继承扩展的方式,它将变成N*N的方式,有N个超类要映射到N个子类,复杂程度是N*N,用装饰者模式将变成N的关系,复杂度将降一个级别。
二.策略模式原理
1.模拟鸭子项目
从项目“模拟鸭子游戏”开始。父类实现基本方法和功能,不清楚的方法交给子类去实现。
2.项目的新需求
给鸭子增加飞的功能。OO设计方法的代码:
Duck.java
package com.bijian.study.oo; /** * 鸭的抽象类 * @author bijian * */ public abstract class Duck { public Duck() { } public void quack() { System.out.println("~~gaga~~"); } public abstract void display(); public void swim() { System.out.println("~~im swim~~"); } public void fly() { System.out.println("~~im fly~~"); } }
GreenHeadDuck.java
package com.bijian.study.oo; /** * 绿头鸭 * @author bijian * */ public class GreenHeadDuck extends Duck { @Override public void display() { System.out.println("**GreenHead**"); } @Override public void fly() { System.out.println("~~no fly~~~"); } }
RedHeadDuck.java
package com.bijian.study.oo; /** * 红头鸭 * @author bijian * */ public class RedHeadDuck extends Duck { @Override public void display() { System.out.println("**RedHead**"); } }
StimulateDuck.java
package com.bijian.study.oo; /** * 主方法 * @author bijian */ public class StimulateDuck { public static void main(String[] args) { GreenHeadDuck mGreenHeadDuck = new GreenHeadDuck(); RedHeadDuck mRedHeadDuck = new RedHeadDuck(); mGreenHeadDuck.display(); mGreenHeadDuck.quack(); mGreenHeadDuck.swim(); mGreenHeadDuck.fly(); mRedHeadDuck.display(); mRedHeadDuck.quack(); mRedHeadDuck.swim(); mRedHeadDuck.fly(); } }
运行结果:
**GreenHead** ~~gaga~~ ~~im swim~~ ~~no fly~~~ **RedHead** ~~gaga~~ ~~im swim~~ ~~im fly~~
3.用OO原则解决新需求的不足
这个fly让所有子类都会飞了,这是不科学的。
继承的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分,影响会有溢出效果。超类挖的一个坑,每个子类都要来填,增加工作量,复杂度O(N^2),不是好的设计方式。
a.继续尝试用OO原理来解决,那就是在子类中覆盖父类的方法。
但如果子类非常多,需要在太多的子类中去覆盖父类的方法。
b.只在子类中实现对应的方法,需要的实现飞,不需要的不实现。但这样代码没有复用了,重复代码出现,代码复用性降低。
且如果又有新的需求,如石头鸭子,它既不会飞,也不会叫,也不会游泳。所有的方法都要覆盖掉。
4.用策略模式来解决新需求
需要新的设计方式,应对项目的扩展性,降低复杂度。
a.分析项目变化与不变部分,提取变化部分,抽象成接口+实现
b.鸭子哪些功能是会根据新需求变化的?叫声、飞行...,抽象成接口,形成行为族
c.好处:新增行为简单,行为类更好的复用,组合更方便。既有继承带来的复用好处,没有挖坑。
5.重新设计模拟鸭子项目
/** * 抽象类里面加了两个行为对象 * 具体飞、叫不具体实现,直接调用行为的实现 * @author bijian * */ public abstract class Duck { FlyBehavior mFlyBehavior; QuackBehavior mQuackBehavior; public Duck() { } public void fly() { mFlyBehavior.fly(); } public void Quack() { mQuackBehavior.quack(); } public abstract void display(); }
6.总结策略模式定义
绿头鸭、石头鸭在构造方法用new一个行为族对象来展现它的行为,而不是具体把行为代码写在类的对象里。
策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者。
三.策略模式示例演示
FlyBehavior.java
package com.bijian.study.strategy.flybehavior; /** * 飞行行为 * @author bijian * */ public interface FlyBehavior { void fly(); }
BadFlyBehavior.java
package com.bijian.study.strategy.flybehavior.impl; import com.bijian.study.strategy.flybehavior.FlyBehavior; public class BadFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("--BadFly--"); } }
GoodFlyBehavior.java
package com.bijian.study.strategy.flybehavior.impl; import com.bijian.study.strategy.flybehavior.FlyBehavior; public class GoodFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("--GoodFly--"); } }
NoFlyBehavior.java
package com.bijian.study.strategy.flybehavior.impl; import com.bijian.study.strategy.flybehavior.FlyBehavior; public class NoFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("--NoFly--"); } }
QuackBehavior.java
package com.bijian.study.strategy.quackbehavior; /** * 叫的行为 * @author bijian * */ public interface QuackBehavior { void quack(); }
GaGaQuackBehavior.java
package com.bijian.study.strategy.quackbehavior.impl; import com.bijian.study.strategy.quackbehavior.QuackBehavior; public class GaGaQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("~~gaga~~"); } }
GeGeQuackBehavior.java
package com.bijian.study.strategy.quackbehavior.impl; import com.bijian.study.strategy.quackbehavior.QuackBehavior; public class GeGeQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("~~gege~~"); } }
NoQuackBehavior.java
package com.bijian.study.strategy.quackbehavior.impl; import com.bijian.study.strategy.quackbehavior.QuackBehavior; public class NoQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("~~NoQuack~~"); } }
Duck.java
package com.bijian.study.strategy.duck; import com.bijian.study.strategy.flybehavior.FlyBehavior; import com.bijian.study.strategy.quackbehavior.QuackBehavior; /** * 抽象类里面加了两个行为对象 * 具体飞、叫不具体实现,直接调用行为的实现 * @author bijian * */ public abstract class Duck { FlyBehavior mFlyBehavior; QuackBehavior mQuackBehavior; public void setmFlyBehavior(FlyBehavior mFlyBehavior) { this.mFlyBehavior = mFlyBehavior; } public void setmQuackBehavior(QuackBehavior mQuackBehavior) { this.mQuackBehavior = mQuackBehavior; } public Duck() { } public void fly() { mFlyBehavior.fly(); } public void quack() { mQuackBehavior.quack(); } public abstract void display(); public void swim() { System.out.println("--im swim--"); } }
GreenHeadDuck.java
package com.bijian.study.strategy.duck; import com.bijian.study.strategy.flybehavior.impl.GoodFlyBehavior; import com.bijian.study.strategy.quackbehavior.impl.GaGaQuackBehavior; public class GreenHeadDuck extends Duck { public GreenHeadDuck() { mFlyBehavior = new GoodFlyBehavior(); mQuackBehavior = new GaGaQuackBehavior(); } @Override public void display() { System.out.println("**GreenHead**"); } }
RedHeadDuck.java
package com.bijian.study.strategy.duck; import com.bijian.study.strategy.flybehavior.impl.BadFlyBehavior; import com.bijian.study.strategy.quackbehavior.impl.GeGeQuackBehavior; public class RedHeadDuck extends Duck { public RedHeadDuck() { mFlyBehavior = new BadFlyBehavior(); mQuackBehavior = new GeGeQuackBehavior(); } @Override public void display() { System.out.println("**RedHead**"); } }
StimulateDuck.java
package com.bijian.study.strategy; import com.bijian.study.strategy.duck.Duck; import com.bijian.study.strategy.duck.GreenHeadDuck; import com.bijian.study.strategy.duck.RedHeadDuck; import com.bijian.study.strategy.flybehavior.impl.NoFlyBehavior; import com.bijian.study.strategy.quackbehavior.impl.NoQuackBehavior; public class StimulateDuck { public static void main(String[] args) { Duck mGreenHeadDuck = new GreenHeadDuck(); Duck mRedHeadDuck = new RedHeadDuck(); mGreenHeadDuck.display(); mGreenHeadDuck.fly(); mGreenHeadDuck.quack(); mGreenHeadDuck.swim(); mRedHeadDuck.display(); mRedHeadDuck.fly(); mRedHeadDuck.quack(); mRedHeadDuck.swim(); mRedHeadDuck.display(); //在使用过程中动态的改变它的行为 System.out.println("-------------------------"); mRedHeadDuck.setmFlyBehavior(new NoFlyBehavior()); mRedHeadDuck.fly(); System.out.println("-------------------------"); mRedHeadDuck.setmQuackBehavior(new NoQuackBehavior()); mRedHeadDuck.quack(); } }
运行结果:
**GreenHead** --GoodFly-- ~~gaga~~ --im swim-- **RedHead** --BadFly-- ~~gege~~ --im swim-- **RedHead** ------------------------- --NoFly-- ------------------------- ~~NoQuack~~
四.策略模式的注意点
1.分析项目中变化部分与不变部分
在鸭子项目里,飞行和叫声是变化的,所以将其抽取出来,将其抽象成接口和具体实现对象(接口和对象行为族)。
2.多用组合少用继承;用行为类组合,而不是行为的继承。更有弹性
行为族对象的组合,行为族之间是独立的。
3.设计模式有没有相应的库直接使用?有些库或框架本身就用某种设计模式设计的
没有,它是经验的总结,是一个方法。用这种模式方法设计类、行为、接口。当然,很多库、框架就是用设计模式设计出来的。
4.如果找不到适用的模式怎么办
进一步分析项目,基本上都能用某种模式或多种模式的组合解决。当然,如果真遇到这种项目,那就是用OO基本原则,抽象、分析设计超类、继承、子类方法来做。
相关推荐
Java设计模式之策略模式的详细描述
55-Java设计模式之策略模式与状态模式1
java设计模式之策略模式实现源码
NULL 博文链接:https://lfl2011.iteye.com/blog/1693685
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,...
主要为大家详细介绍了Java设计模式之策略模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...
主要介绍了Java设计模式之策略模式(Strategy模式)介绍,Strategy是属于设计模式中对象行为型模式,要是定义一系列的算法,这些算法一个个封装成单独的类,需要的朋友可以参考下
设计模式之装饰模式Java实现和UML类设计图
2、爪哇语言抽象工厂创立性模式介绍 3、工厂方法创立性模式介绍 4、单态创立性模式介绍 5、单态创立性模式介绍 6、观察者模式介绍7、责任链模式 8、设计模式之Observer 9、设计模式之Strategy(策略) 10、设计模式之...
创建模式: 设计模式之Factory 设计模式之Prototype(原型) 设计模式之Builder 设计模式之Singleton(单态) ...设计模式之Strategy(策略) 设计模式之Mediator(中介者) 设计模式之Interpreter(解释器) 设计模式之Visitor
主要介绍了Java设计模式之策略模式定义与用法,结合具体实例形式详细分析了Java策略模式的概念、原理、定义及相关操作技巧,需要的朋友可以参考下
JAVA设计模式demo之策略模式,解压代码可以直接运行。谁能告诉我,为什么资源分不能搞成0分?!
代码为博客的例子,详细讲解参考:http://blog.csdn.net/lmj623565791/article/details/24116745 有问题请留言
策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换。接下来通过本文给大家分享Java设计模式之策略模式,感兴趣的朋友一起看看吧
主要介绍了Java设计模式之策略模式原理与用法,结合实例形式较为详细的分析了Java策略模式的概念、原理、定义及使用方法,并总结了相关的优缺点,具有一定参考借鉴价值,需要的朋友可以参考下