您的位置:首页 > 编程语言 > Java开发

Java设计模式:九、生成器模式

2017-06-19 20:17 197 查看

生成器模式

就这几天,花了两天辛辛苦苦写了一个导出数据的需求。换了好几种方案(在这之前我并没有看过生成器模式)。然后最终我把方案的实现定格在了策略模式。今天突然看到生成器模式,我在想,它们究竟有什么不同呢。

需求

先描述一下这个导出数据的需求:

Java Web项目,将数据库的某张表根据不同的条件将数据导出为不同格式的文件。比如Excel文件、CSV文件。

实现的基本步骤是:

读取需要导出的数据 –> 生成需要的格式 –> 将生成的对象写入本地磁盘 –> 读取本地磁盘文件上传至阿里云空间返回URL地址提供别人下载。

大致流程是这样的。

当时在不知道生成器模式的时候,换了好几种方案。最后将实现定格在了“策略模式”。

策略模式是:一群具有相同类型的对象,如果存在不同的行为,可以将这个行为独立出来,让每个对象依赖自己需要的行为。

我根据这一点,定义了一个ExportServer,提供了公共的方法:写入对象到磁盘、上传至阿里云空间并返回URL。然后读取数据分别由子类来实现(导出不同的表)。而生成需要的格式,依赖需要的行为。

大概结构:

public interface Action {
T buildFile();
}

public class ExcelAction implements Action<Workbook> {
public Workbook buildFile(){
//封装Workbook
}
}

pubilc class CSVAction implements Action<CSVPrint> {
public CSVPrint buildFile(){
//封装Workbook
}
}

public abstract class ExportServer {
public abstract T readData();

public abstract Y buildWriter();

public void dataToLocal(){
//将已经构建好的File写在本地磁盘
}

public void uploadFileToOss(){
//将本地文件上传至OSS(阿里云存储空间)
}

}

public class EntityAExportServer extends ExportServer {
//导出Excel文件。这个行为可以由外部传入,让调用者决定导出什么类型
private Action action = new ExcelAction();

public abstract EntityA readData(){
//从数据库中获取数据
}

public Workbook buildWriter(){
action.buildFile();
}
}

public class EntityBExportServer extends ExportServer {
//导出CSV文件
private Action action = new CSVAction();

public abstract EntityA readData(){
//从数据库中获取数据
}

public CSVPrint buildWriter(){
action.buildFile();
}
}
//其他同理

public class Test {
public static void main(String[] args){
ExportServer exportServer = new EntityAExportServer();
exportServer.readData();
exportServer.buildWriter();
exportServer.dataToLocal();
exportServer.uploadFileToOss();
}
}


当时的思路是在策略模式上面。感觉这个设计很完美。今天偶然看到了生成器模式。一开始的感觉是,这不就是策略模式么?

生成器模式

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

这儿注意:同样的构建过程。

假设上面的需求,数据已经固定,根据这个数据,导出不同形式的文件。按照生成器的定义,构建过程与表示分离。

如果不使用模式,会这样写:

public class ExportExcel {
public void buildFile(){
//封装Excel文件对象
}

public void dataToLocal(){
//将封装的文件对象写到本地
}
public void uploadFileToOss(){
//将本地文件上传至阿里云存储空间
}
}

public class ExportCSV {
public void buildFile(){
//封装CSV文件对象
}

public void dataToLocal(){
//将封装的文件对象写到本地
}
public void uploadFileToOss(){
//将本地文件上传至阿里云存储空间
}
}


使用生成器,将buildFile独立出来。

public interfacce Build {
void buildFile();
}

public class BuildExcel implements Build {
public void buildFile(){
//封装EXCEL文件对象
}
}

public class BuildCSV implements Build {
public void buildFile(){
//封装CSV文件对象
}
}

public class Export {
build build;
public Export(Build build){
this.build = build;
}
public void buildFile(){
build.buildFile();
}

public void dataToLocal(){
//将封装的文件对象写到本地
}
public void uploadFileToOss(){
//将本地文件上传至阿里云存储空间
}
}


我一看生成器模式,不就是策略模式单个化了嘛。为什么要把它们分为两种不同的模式呢?

其实严格来说,我上面使用的那个所谓的“策略模式”,是一个“生成器模式”。策略模式的定义是,每一个子类的行为都是独立的,和他的其他行为没有相关联,是可以独立存在的。

例如动物类:

它们具有相同的行为是,可以吃饭,可以睡觉。不同的行为是:行走方式不同。小鸟飞着走,小猫小狗走着走,鱼儿虾类游着走,青蛙乌龟又能走又能游。这些不同的行为,和公有的行为是没有关联的。

而生成器模式:

构建与表示分离,生成需要的格式 –> 将生成的对象写入本地磁盘 –> 上传至阿里云空间。这个过程属于一个构建产品的过程,不同的生成方式,构建出来的产品不同。

生成器模式的主要功能是构建复杂产品,一个产品的构建过程是统一的,不变的,只是构建什么样的产品,将这个不同点独立在生成器中,只要配置不同的生成器,那么同样的构建过程,就能构建出不同的产品来。

整体来看,我还是很容易把这两种模式给混淆。如果非要我区分个哪是策略哪是生成器,我会根据他们的操作来区分。如果是一个对象的行为,则为策略模式。如果是一个对象的生成过程,则为生成器模式。

以上是个人对生成器模式与策略模式的理解与比较。也许有些地方写的很乱,不明白。如有大神有其他不同的理解,请多多评论指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: