【“别跟我不会”系列】Java设计模式之策略模式

茶余饭后的IT小知识,不说了,都是干货。 —— 23号老板

0

1

引入

原创:爱吃回锅肉的瘦子

一直以来,笔主想写关于设计模式的系列文章与大家进行交流,但碍于自己经验上尚浅,无法将此讲解透彻,闹了笑话。但千里之行,始于足下,我决定将我自己的工作中我用到的设计模式与大家分享交流,有不妥还望大家指出。

设计模式一种设计开发上的经验总结,既然是经验上的总结,那么实践是必然的;但他又是一种设计,所以在我们对需求必须得非常了解,对他可能以后出现什么样的变化有个预测。此次我打算先从设计模式中的策略模式讲起。

0

2

概念

在策略模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

代码上的设计上大体架构:

1、抽象的行为:

  public interface Behavior {
    public void toDo();
}

2、实现抽象行为的两个类

public class OneBehavior implements Behavior{ @Override public void toDo() { System.out.println("one"); } }

public class TwoBehavior implements Behavior {
    @Override
    public void toDo() {
        System.out.println("two");
    }
}

3、定义公有的行为类:

public class DataBase {
    protected Behavior behavior;

    public DataBase(Behavior behavior) {
        this.behavior = behavior;
    }
    public void query(){
        behavior.toDo();
    }
    public void delete(){
        System.out.println("delete");
    }

}

从上面代码架构上看,可以看到策略模式的方式本身就是将本身属于database中的某些方法抽离出来,用接口的方式来抽象方法。既然这样,那与我们常用的模板模式有什么区别呢?

为何不将database设计成抽象类,然后将此进行各个子类实现,我们也可以做到不同方法的实现。注意设计模式是结合具体场景而使用的一种经验模式。

0

3

深入

那么在什么样的场景下使用策略模式,有什么样的场景下使用模板模式呢?

我们知道,在对代码评价有个复用性比较,那么我们可以假设这样的一个场景

假设在query方法中 我们目前只有两种的查询逻辑方式,但是有9个查询需要使用,其中有6个是使用相同的query()。这样的话,在使用模板模式中我们对query()方法要写6个相同的代码。的确,我们还可以将这6个中再写一个父类继承,此父类再继承database,但是delete方法中在这6个有三个delete相同呢又或者其中三个delete方法又与前面3个子类相同呢?

这时候我们用模板模式来实现不同的方法是不可行的。必须将方法解耦化,如何解耦呢?将变化的方法抽象成接口,将database依赖于该接口,也就是说我们可以将接口作为属性给予database。综上,在笔主看来,策略模式就是将一些多变的方法抽象出来,来增加代码的复用。

注意点:

1、分析项目中的变化部分与不变部分;

2、多用组合少用继承;用行为类组合,而不是行为的继承,更有弹性;

0

4

实战部分

笔主是主要开发报表功能的,难免牵扯到生成excel。我这边生成excel有三种方式,poi,easyExcel,以及第三方软件。他们各个使用方式有不同的划分。如果想了解Excel是如何使用poi解析的可以看看前面的文章。(如果找不见,可加微信bboyHan索要)

那么我那时候为啥选择使用策略模式,是基于什么样的考量呢?这里就开始讨论方法论了。刚开始的时候 ,获取Excel不是那么复杂, 我只是单纯的使用POI方式生成excel,后面由于有性能上要求,就使用上了easyExcel,在后来excel表格复杂化了,为了便于维护就使用上了第三方软件功能,再后来运营还要求导出pdf。当然了,这些是需求在讨论时候就已经确认要分多次迭代了。如果是三张报表,分别用这三个获取excel方式,那简单使用mvc模型就差不多解决了。但是笔主面对的是几百张报表,必须得将此抽离出来所有的导出功能。也就是我设计一个接口 getFile(),三个行为类poi、easyExcel、第三方实现getFile();再写一个参数基本类,将选择什么样方式导出放在此处,然后在写一个获取数据获取类,并依赖getFile类。代码如下:

public interface GetFile {
    public File toDo();
}
public class PoiFile implements GetFile {
    @Override
    public File toDo() {
        System.out.println("poi");
        return new File("poi");
    }
}
public class EasyExcelFile implements GetFile {
    @Override
    public File toDo() {
        System.out.println("EasyExcel");
        return new File("EasyExcel");
    }

}
public class DataBase {
    protected GetFile getFile;

    public DataBase(GetFile behavior) {
        this.getFile = behavior;
    }
    public void query(){
        getFile.toDo();
    }
    public void delete(){
        System.out.println("delete");
    }

}
public class TwoData extends DataBase {

    public TwoData(GetFile file) {
        super(file);
    }

    @Override
    public void query() {
        this.getFile.toDo();
    }
}
public class OneData extends DataBase{

    public OneData(GetFile getFile) {
        super(getFile);
    }
    @Override
    public void query() {
        this.getFile.toDo();
    }
}

参数类:

public class RequestModel implements Serializable {
    private String type;
   
    public GetFile getFile(){
        if("POI".equalsIgnoreCase(getType()))return new PoiFile();
        else return new EasyExcelFile();
    }

    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
}

service层:

//交给sring管理DataBase dataBase;
public void query(RequestModel rq){
     dataBase.query();
}

0

5

小结

以上就是策略模式实现方式,简单来说,可以理解为将多变的方法抽离出来,进行解耦合。

本文分享自微信公众号 - 23号杂货铺(sharontang0323)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小黎子数据分析

总结Oracle8i 的UNDO表空间损坏(ORA-01092及ORA-00600【4193】)情况下的数据库不完全恢复的经历

服务器断电重启导致备份生产环境的恢复目录库无法进行启动,提示Ora-01092例程终止。强行断开连接

8140
来自专栏小黎子数据分析

数据仓库系列之关于数据仓库自动化技术

  目前市面上的BI工具都在提及敏捷BI解决方案。敏捷BI解决方案所提供的自动化技术支持主要是从数据源取数到BI前端工具展现。这样的敏捷BI解决方案在企业数据量...

12630
来自专栏小黎子数据分析

数据仓库系列之数据质量管理

  数据质量一直是数据仓库领域一个比较令人头疼的问题,因为数据仓库上层对接很多业务系统,业务系统的脏数据,业务系统变更,都会直接影响数据仓库的数据质量。因此数据...

27010
来自专栏北京宏哥

互联网App应用程序测试流程及测试总结

测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日),根据项目情况以及版本质量可适当缩短或延长测试时间。正式测试前先向主管确认项目排...

14530
来自专栏北京宏哥

python接口自动化(二十)--token登录(详解)

  为了验证用户登录情况以及减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。有些登录不是用 cookie 来验证的,是用 token 参数来判断是否...

23430
来自专栏北京宏哥

python接口自动化(二十二)--unittest执行顺序隐藏的坑(详解)

  大多数的初学者在使用 unittest 框架时候,不清楚用例的执行顺序到底是怎样的。对测试类里面的类和方法分不清楚,不知道什么时候执行,什么时候不执行。虽然...

29430
来自专栏Creator星球游戏开发社区

微信云开发使用教程

微信云开发技术可以让我们免费方便的使用服务器的部分功能,对于微信小游戏非常有帮助。

38820
来自专栏逸繁

什么是ORM?

一、ORM简介 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不...

8820
来自专栏逸繁

MySQL入门详解(二)---mysql事务、锁、以及优化

1.脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

11050
来自专栏穆书伟

再不了解PostgreSQL,你就晚了之PostgreSQL主从流复制部署

在MySQL被收购之后,虽然有其替代品为: MariaDB,但是总感觉心里有点膈应。大家发现了另一款开源的数据库: PostgreSQL。

29220

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励