前言

如果说,商场打折针对不同的时节,比如双十一、圣诞节、春节这些值得促销的好日子,进行不同程度的降价打折从而获得最大程度上的收益,如果有一群鸭子,只会游泳、嘎嘎叫,但是某一天某种类型的鸭子学会了飞,那群里面的鸭子并不会飞。这样的话还有修改以前的封装好的算法,然后添加飞翔的功能,这个时候,就得考虑一下设计原则。对扩展开放,对修改封闭。针对这种算法经常变化的情况,将这些算法封装起来,独立于不变的成分,保证增加新的算法的同时,对不变的地方不添加修改。下面采用 Strategy
Pattern 进行实现。分别从UML图分析和代码两个方面进行分析。

内容

精华:

定义了算法族,分别封装起来,让它们之间相互替换,此模式让算法的变化独立于使用算法的客户。

原则:

·将变化的地方封装起来了(封装变化)。

·多用组合,少用继承。

·针对接口编程,不针对实现。

UML图

DEMO部分:

说明:以下的代码为左半部分抽象类与子类继承抽象类,从而子类继承抽象类的属性和行为,其中的setFlyBehavior和setQuackBehavior方法作用可以在客户端调用该对象的时候动态添加鸭子的行为。

<span style="font-family:KaiTi_GB2312;font-size:18px;">package Duck;

/*
* author:zhoulitong
*/
abstract class Duck{
FlyBehavior flyBehavior;
QuackBehavior quackBehavior; //表演一个叫的动作
public void performQuack(){
quackBehavior.quack();
} //表演一个飞的动作
public void performFly(){
flyBehavior.fly();
} public abstract void display(); //有了这个方法可以动态改变鸭子的行为了
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
} public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
} class MallardDuck extends Duck{
public MallardDuck(){
quackBehavior = new Quack();//实例化叫的实例
flyBehavior = new FlyWithWings();//实例化飞的实例
} public void display(){
System.out.println("小鸭是一个真正的鸭子!不是白天鹅");
}
}</span>

说明:接口部分,这部分的代码是封装了变化的部分,从而让变化的部分独立于不变的部分,让这个设计模式更加的符合开闭原则,在这里,接口部分盛放的是鸭子的功能,鸭子表现行为的时候,分别利用多态进行按需求实例化自己想要的那部分功能行为。

<span style="font-family:KaiTi_GB2312;font-size:18px;">/*
* author:zhoulitong
*/
//声明一个公共接口(类似于抽象类的功能)
interface QuackBehavior {
void quack();//声明一个呱呱叫的方法
} class Quack implements QuackBehavior{
public void quack(){
//实现鸭子呱呱叫
}
} class Squeak implements QuackBehavior{
public void quack(){
//实现橡皮鸭吱吱叫的方法
}
} class MuteQuack implements QuackBehavior{
public void quack(){
//什么都不做,不会叫
}
} interface FlyBehavior{
void fly();//声明一个飞的接口方法
} class FlyWithWings implements FlyBehavior{
public void fly(){
//实现鸭子的飞行动作
}
} class FlyNoWay implements FlyBehavior{
public void fly(){
//什么都不做,不会飞
}
} class FlyRocketPowered implements FlyBehavior{
public void fly(){ }
}</span>

说明:客户端代码部分,申请一个对象的实例,采用了多态机制,实例化了一个实际存在的鸭子对象,分别执行行为。

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class MiniDuckSimulator{
public static void main (String[] args){
Duck mallard = new MallardDuck();//实例化一个鸭子
mallard.performFly();//飞的动作
mallard.performQuack();//叫的动作 //如果又增加了一个动作,可以通过Duck父类中的set方法对实例化的对象进行附加
//在运行时想要改变鸭子的行为,只需要调用鸭子的setter方法就可以了。
mallard.setFlyBehavior(new FlyRocketPowered());
mallard.performFly();
}
}</span>

小结

上面就是策略模式一个小小的应用,希望在后期有更多实践。

感谢您的宝贵时间···

【Java】Strategy Pattern的更多相关文章

  1. 【Java】Observer Pattern

    前言 代码来源于生活,更加高于生活.设计模式让我们的生活更加的方便.观测一个东西,盯着一个东西,关注一个公众号,这些东西,如果没有即时通知的话,我们又特别想了解这方面的内容,那么我们除了一直耗着时间找 ...

  2. 【Java】-NO.20.Exam.1.Java.1.001- 【1z0-807】- OCEA

    1.0.0 Summary Tittle:[Java]-NO.20.Exam.1.Java.1.001-[1z0-807] Style:EBook Series:Java Since:2017-10- ...

  3. 【Java】-NO.16.EBook.4.Java.1.007-【疯狂Java讲义第3版 李刚】- Java基础类

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.007-[疯狂Java讲义第3版 李刚]-  Java基础类 Style:EBook Series:J ...

  4. 【Java】-NO.11.Java.1.Log4j.1.001-【Log4j Manual】-

    1.0.0 Summary Tittle:[Java]-NO.11.Java.1.Log4j.1.001-[Log4j2 Manual]- Style:Java Series:Log4j Since: ...

  5. 数据结构与算法【Java】03---栈

    前言 数据 data 结构(structure)是一门 研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构才可以编写出更加漂亮,更加有效率的代码. 要学习好数据结构就要多多考虑如何将生 ...

  6. 【Java】代处理?代理模式 - 静态代理,动态代理

    >不用代理 有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码. 这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果.(至于为什么不直接用+号运算, ...

  7. 【Java】推断文件的后缀名

    这本来不是一个问题,利用框架本来有的方法.或者File类的getPath()方法,取出要推断文件路径.或者getName()方法取出文件路径,成为一个String字符串如果为fileName之后,再对 ...

  8. 【JAVA】【NIO】3、Java NIO Channel

    Java NIO和流量相似,但有些差异: ·通道可读写,流仅支持单向.读或写 ·异步通道读取 ·通道读写器,他们是和Buffer交替 道的实现 下面是Java NIO中最重要的通道的实现: ·File ...

  9. 【JAVA】【NIO】5、Java NIO Scatter / Gather

    标题手段Java NIO该分散体浓缩 Java NIO内置支持分散与收集.的概念主要用于信道分散聚集的读写. 读出的分散体的一个通道被读多个数据buffer在.因此.数据分散到多个buffer中. 对 ...

随机推荐

  1. Spring Boot自定义配置与加载

    Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...

  2. mybatis 学习四 (上)resutlMap

    SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用,例如: ...

  3. Mysql教程:[1]下载安装配置详细教程

    如果不小心你下载了免安装的mysql,那么你比较倒霉,你找不到setup文件,还得自己去配置很多东西,然后再使用命令安装.所以我今天呢写一篇教程,写的尽量详细,即便是菜鸟也能安装,我自己安装过很多遍了 ...

  4. Java事务的原理与应用

    Java事务的原理与应用 一.什么是Java事务 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (isolation ...

  5. FFmpeg for Android compiled with x264, libass, fontconfig, freetype and fribidi

    android下打算使用ffmpeg的 drawtext ,不过需要 --enable-libfreetype  但是freetype是个第三方库,所以需要先编译freetype,然后再编译ffmpe ...

  6. DAY15-web框架本质及第一个Django实例

    Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义web框架 impor ...

  7. JS中,根据div数值判断弹出窗口

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. nodejs的POST请求

    http://blog.csdn.net/puncha/article/details/9015317 Nodejs 发送HTTP POST请求实例 2013-06-03 17:55 71745人阅读 ...

  9. 第6章 使用springboot整合netty搭建后台

    我们不会去使用自增长的id,在现阶段的互联网开发过程中,自增长的id是已经不适用了.在未来随着系统版本的迭代,用户数量的递增,肯定会做分库分表,去做一些相应的切分.在这个时候我们就需要有一个唯一的id ...

  10. easyui layout 折叠之后显示标题

    方法一:重载扩展panel收缩事件 (function($){ var buttonDir = {north:'down',south:'up',east:'left',west:'right'}; ...