Copyright ©2018
hbgengfei11
一、引言
做文件上传解析时,一个上传入口往往会上传多种类型的待解析文件或者上传的压缩包包含多种类型待解析文件,或者多个上传入口调用后台同一个接口。本文基于这样的场景,在满足多用组合、少用继承的原则下,设计了工厂+策略+模板方法设计模式实现业务需求。具体实现如下:
二、业务接口
package com.test.oneFactoryAndStrategySystem;
/**
* @author admin
* 解析文件调用接口
*/
public interface IService
{
/**
* <解析文件调用接口>
* @param inPutPath
* @param outPathPath
* @param typeId
* @return
*/
String parse(String inPutPath,String outPathPath,int typeId);
}
三、业务接口实现类
package com.test.oneFactoryAndStrategySystem.Impl;
import com.test.oneFactoryAndStrategySystem.IService;
import com.test.oneFactoryAndStrategySystem.factory.AnalysisStrateGyFactory;
import com.test.oneFactoryAndStrategySystem.strategy.AbstractStrategyTemplate;
/**
* @author admin
*
*/
public class SomeService implements IService
{
/*
* 解析接口实现方法
*/
@Override
public String parse(String inPutPath, String outPathPath, int typeId)
{
AbstractStrategyTemplate handle = AnalysisStrateGyFactory.buildStratey(inPutPath, outPathPath, typeId);
long successNum = handle.analysis();
String message = "成功解析" + successNum + "条数据";
return message;
}
}
四、选择策略工厂
package com.test.oneFactoryAndStrategySystem.factory;
import com.test.oneFactoryAndStrategySystem.strategy.AbstractStrategyTemplate;
import com.test.oneFactoryAndStrategySystem.strategy.CSVAnalysisHandle;
import com.test.oneFactoryAndStrategySystem.strategy.ExcelAnalysisHandle;
import com.test.oneFactoryAndStrategySystem.strategy.XMLAnalysisHandle;
/**
* @author admin
* 选择策略工厂
*/
public class AnalysisStrateGyFactory
{
public static AbstractStrategyTemplate buildStratey(String inPutPath, String outPathPath, int typeId)
{
AbstractStrategyTemplate handle = null;
//根据需要文件typeId选择具体策略
switch(typeId)
{
case 101:
//解析CSV文件
handle = new CSVAnalysisHandle(inPutPath, outPathPath, typeId);
break;
case 102:
//解析Excel文件
handle = new ExcelAnalysisHandle(inPutPath, outPathPath, typeId);
break;
case 103:
//解析XML文件
handle = new XMLAnalysisHandle(inPutPath, outPathPath, typeId);
break;
}
return handle;
}
}
五、模板方法
package com.test.oneFactoryAndStrategySystem.strategy;
/**
* @author admin
* 模板方法
*/
public abstract class AbstractStrategyTemplate
{
/**
* 文件类型是否正确
*/
public final boolean checkFileType(String inputPath,String suffix)
{
if(inputPath.endsWith(suffix))
{
return true;
}
return false;
}
/**
* 文件解析主方法
*/
public abstract long analysis();
/**
* 钩子方法,子类可重写
*/
public void writeFile(String outPathPath)
{
System.out.println("默认写出CSV文件");
}
}
六、策略一
package com.test.oneFactoryAndStrategySystem.strategy;
import org.apache.log4j.Logger;
/**
* @author admin
* 解析CSV类型文件handle
*
*/
public class CSVAnalysisHandle extends AbstractStrategyTemplate
{
private static Logger logger = Logger.getLogger(CSVAnalysisHandle.class);
/**
* 文件输入路径
*/
private String inPutPath;
/**
* 文件输出路径
*/
private String outPathPath;
/**
* 文件类型
*/
private int typeId;
public CSVAnalysisHandle()
{
}
public CSVAnalysisHandle(String inPutPath, String outPathPath, int typeId)
{
super();
this.inPutPath = inPutPath;
this.outPathPath = outPathPath;
this.typeId = typeId;
}
@Override
public long analysis()
{
//成功解析条数计数
long successNum = 0;
//判断是否为需要解析的文件
//文件类型正确,并且typeId正确
if(checkFileType(inPutPath, ".csv") && typeId == 101)
{
System.out.println("解析"+ typeId + "类型的CSV文件,并返回成功解析条数");
//成功解析10条文件
successNum = 10;
//使用默认写出方法,写出CSV文件
writeFile(outPathPath);
}
else
{
logger.error("file type is error");
return 0;
}
return successNum;
}
}
七、策略2
package com.test.oneFactoryAndStrategySystem.strategy;
import org.apache.log4j.Logger;
/**
* @author admin
* 解析Excel类型文件handle
*
*/
public class ExcelAnalysisHandle extends AbstractStrategyTemplate
{
private static Logger logger = Logger.getLogger(ExcelAnalysisHandle.class);
/**
* 文件输入路径
*/
private String inPutPath;
/**
* 文件输出路径
*/
private String outPathPath;
/**
* 文件类型
*/
private int typeId;
public ExcelAnalysisHandle()
{
}
public ExcelAnalysisHandle(String inPutPath, String outPathPath, int typeId)
{
super();
this.inPutPath = inPutPath;
this.outPathPath = outPathPath;
this.typeId = typeId;
}
@Override
public long analysis()
{
//成功解析条数计数
long successNum = 0;
//判断是否为需要解析的文件
//文件类型正确,并且typeId正确
if(checkFileType(inPutPath, ".xlsx") && typeId == 102)
{
System.out.println("解析"+ typeId + "类型的xml文件,并返回成功解析条数");
//成功解析10条文件
successNum = 10;
//使用默认写出方法,写出xml文件
writeFile(outPathPath);
}
else
{
logger.error("file type is error");
return 0;
}
return successNum;
}
}
八、策略3
package com.test.oneFactoryAndStrategySystem.strategy;
import org.apache.log4j.Logger;
/**
* @author admin
* 解析XML类型文件handle
*
*/
public class XMLAnalysisHandle extends AbstractStrategyTemplate
{
private static Logger logger = Logger.getLogger(ExcelAnalysisHandle.class);
/**
* 文件输入路径
*/
private String inPutPath;
/**
* 文件输出路径
*/
private String outPathPath;
/**
* 文件类型
*/
private int typeId;
public XMLAnalysisHandle()
{
}
public XMLAnalysisHandle(String inPutPath, String outPathPath, int typeId)
{
super();
this.inPutPath = inPutPath;
this.outPathPath = outPathPath;
this.typeId = typeId;
}
@Override
public long analysis()
{
//成功解析条数计数
long successNum = 0;
//判断是否为需要解析的文件
//文件类型正确,并且typeId正确
if(checkFileType(inPutPath, ".xml") && typeId == 103)
{
System.out.println("解析"+ typeId + "类型的xml文件,并返回成功解析条数");
//成功解析10条文件
successNum = 10;
//使用默认写出方法,写出xml文件
writeFile(outPathPath);
}
else
{
logger.error("file type is error");
return 0;
}
return successNum;
}
/*
* 重写钩子方法,写出Excel文件
*/
@Override
public void writeFile(String outPathPath)
{
System.out.println("写出Excel文件");
}
}
九、Test
package com.test.oneFactoryAndStrategySystem.test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.test.oneFactoryAndStrategySystem.IService;
import com.test.oneFactoryAndStrategySystem.Impl.SomeService;
/**
* @author admin
* 测试类
*
*/
public class MyTest
{
/**
* 解析调用
*/
private IService service;
/**
* 文件输入路径
*/
private String inPutPath;
/**
* 文件输出路径
*/
private String outPathPath;
/**
* 文件类型
*/
private int typeId;
/**
* 解析完成返回值
*/
private String message;
@Before
public void before()
{
service = new SomeService();
}
@After
public void after()
{
//控制台数据返回消息
System.out.println(message);
}
/**
* 解析CSV文件测试类
*/
@Test
public void CSVAnalysisTest()
{
inPutPath = "C:\\Users\\test\\Desktop\\1.csv";
outPathPath = "C:\\Users\\test\\Desktop\\1\\";
typeId = 101;
message = service.parse(inPutPath, outPathPath, typeId);
}
/**
* 解析Excel文件测试类
*/
@Test
public void ExcelAnalysisTest()
{
inPutPath = "C:\\Users\\test\\Desktop\\1.xlsx";
outPathPath = "C:\\Users\\test\\Desktop\\1\\";
typeId = 102;
message = service.parse(inPutPath, outPathPath, typeId);
}
/**
* 解析XML文件测试类
*/
@Test
public void XMLAnalysisTest()
{
inPutPath = "C:\\Users\\test\\Desktop\\1.xml";
outPathPath = "C:\\Users\\test\\Desktop\\1\\";
typeId = 103;
message = service.parse(inPutPath, outPathPath, typeId);
}
}
十、结果
解析103类型的xml文件,并返回成功解析条数
写出Excel文件
成功解析10条数据
解析101类型的CSV文件,并返回成功解析条数
默认写出CSV文件
成功解析10条数据
解析102类型的xml文件,并返回成功解析条数
默认写出CSV文件
成功解析10条数据