一.设计模式入门
设计模式是人们在面对同类型软件工程设计问题所总结出的一些有用经验。模式不是代码,而是某类问题的通用设计解决方案。
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设计模式中的行为模式之一,它的核心思想是定义一系列的算法,并将每一个算法封装起来,使它们可以相互替换。这种模式让算法的变化独立于使用算法的客户。在Java编程中,策略模式常用于处理那些...
Java 设计模式之策略模式与状态模式 策略模式是 Java 中的一种设计模式,它主要用于解决系统与第三方接口进行数据交互的问题。当系统需要与多种格式的数据进行交互时,使用策略模式可以很好地解决这个问题。例如,...
在Java编程领域,设计模式是解决常见问题的可重用解决方案,它们代表了软件设计的最佳实践。本篇文章将深入探讨两种重要的设计模式:策略模式和模板模式。通过理解这两种模式,开发者可以更好地组织代码,提高代码的...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,策略模式主要通过定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换,让算法独立于使用它的客户而变化。 首先,策略模式的...
策略模式是一种设计模式,它允许在运行时动态选择和切换不同的算法或策略,而不影响到使用这些算法的客户端代码。这种模式将策略的定义和使用分开,使得算法的变化不会影响到调用者,同时提供了更好的可扩展性。 在...
Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,策略模式主要通过定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换,让算法独立于使用它的客户而变化。 首先,策略模式的...
在这个“java设计模式-策略模式”的示例中,我们将深入探讨如何使用策略模式来实现一个简单的超市促销系统。 策略模式的核心思想是定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换。这使得算法的...
Java设计模式之策略模式定义与用法详解 策略模式是一种行为设计模式,它定义了一系列算法,把他们一个一个封装起来,并且使他们可以相互替换。策略模式的主要优点是实现了上下文和具体策略的松耦合关系,使得上下文...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,策略模式通常涉及定义一系列算法,将每个算法封装到具有共同接口的独立类中,使得它们可以相互替换。这样做的主要好处是算法的变化不会影响...
Java设计模式是面向对象编程领域中的重要概念,它是一套被广泛接受并实践的解决软件设计问题的经验总结。设计模式并非具体的代码或库,而是一种在特定情境下为了解决常见问题而制定的通用解决方案的描述。它们描述了...
Java设计模式之策略模式 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换。策略模式的定义是:定义一组算法,将每个算法都封装起来,并且使他们之间可以...
策略模式是Java设计模式中的一种非常重要的模式,它可以让算法独立于使用它的客户而独立变化。策略模式定义了一系列的算法,并将每一个算法封装起来,使它们还可以相互替换。 策略模式的组成部分: 1. 抽象策略...
《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...
在这个“JAVA设计模式例程-策略模式”的压缩包中,我们可以深入探讨策略模式的原理及其应用。 策略模式的核心思想是定义一系列算法,并将每一个算法封装起来,使它们可以相互替换。策略对象的使用让算法的变化独立...