【发布时间】:2015-06-05 09:16:22
【问题描述】:
我正在尝试替换简单的工厂 StatsCreatorFactory.java 类,以删除臭气熏天的多次使用 switch case 语句。这是我的情况:
StatsServlet.java
public class StatsServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
StatsContext context = new StatsContext(request,response);
**IStatsCreator creator = StatsCreatorFactory.getCreator(context);**
IChart chart = creator.createChart();
String jsonChart = creator.chartToJson(chart);
creator.sendResponse(jsonChart);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
}
IStatsCreator.java
public interface IStatsCreator {
public IChart createChart() throws IOException;
public IDetailsTable createDetailsTable(String itemSelected);
public String chartToJson(IChart chart);
public String tableToJson(IDetailsTable table);
public void sendResponse(String resp) throws IOException;
public List<File> findFiles() throws IOException, ParseException;
public List<LogLine> parseFiles(List<File> files) throws IOException;
public IFileIntervalDateDetector getFileDetector() throws IOException;
public TargetChartOperation getTargetOperation();
public IChart getChart();
public IDetailsTable getDetailsTable();
}
AbstractStatsCreator
public abstract class AbstractStatsCreator implements IStatsCreator{
protected StatsContext context;
public AbstractStatsCreator(StatsContext context) {
this.context = context;
}
protected abstract ILogParser getParser();
protected abstract IStatsHelper getHelper();
@Override
public IFileIntervalDateDetector getFileDetector() throws IOException {
IFileIntervalDateDetector fileDetector = new FileDetector();
fileDetector.addPattern(new FileNamePattern(TypeSubjectEnum.valueOf(context.getSubject().toUpperCase()).getFilePattern()));
fileDetector.addPattern(new FileNamePattern(context.getInstance()));
return fileDetector;
}
@Override
public final List<File> findFiles() throws IOException, ParseException{
if(context.getDateStart().equalsIgnoreCase(StringUtils.EMPTY) && context.getDateEnd().equalsIgnoreCase(StringUtils.EMPTY)){
return getFileDetector().findDailyFiles();
}
Date startDate = new SimpleDateFormat("ddMMyyyy").parse(context.getDateStart());
Date stopDate = new SimpleDateFormat("ddMMyyyy").parse(context.getDateEnd());
Date currentDate = new Date(System.currentTimeMillis());
if(DateUtils.isSameDay(startDate, stopDate) && DateUtils.isSameDay(startDate, currentDate)){
return getFileDetector().findDailyFiles();
}
return getFileDetector().findFilesByInterval(context.getDateStart(), context.getDateEnd());
}
@Override
public final List<LogLine> parseFiles(List<File> files) throws IOException{
return getParser().parseLogFiles(files);
}
@Override
public IChart createChart() throws IOException{
if(context.needUpdate()){
List<File> files = null;
try {
files = findFiles();
} catch (ParseException e) {
files=Lists.newArrayList();
}
List<LogLine> logLines = parseFiles(files);
context.setLogLines(logLines);
context.updateContext();
}
IChart chart = getChart().create();
return chart;
}
@Override
public IDetailsTable createDetailsTable(String itemSelected) {
IDetailsTable table = getDetailsTable().create(itemSelected);
return table;
}
@Override
public String chartToJson(IChart chart) {
StringBuilder json = new StringBuilder(JsonTransformer.renderChart(chart));
return json.toString();
}
@Override
public String tableToJson(IDetailsTable table) {
StringBuilder json = new StringBuilder(JsonTransformer.renderDetailsTable(table));
return json.toString();
}
@Override
public void sendResponse(String resp) throws IOException {
context.getResponse().setContentType("application/json");
PrintWriter out = context.getResponse().getWriter();
out.write(resp.toString());
out.flush();
}
}
StatsCreatorFactory.java
public class StatsCreatorFactory {
public static IStatsCreator getCreator(StatsContext context){
if(context == null){
throw new IllegalArgumentException("Context nullo");
}
IStatsCreator creator=null;
switch (context.getOperation()) {
case "validate":
creator = new ValidateStatsCreator(context);
break;
case "extract":
creator = new ExtractStatsCreator(context);
break;
case "transform":
creator = new TransformStatsCreator(context);
break;
case "view":
creator = new ViewStatsCreator(context);
break;
default:
creator = new GeneralStatsCreator(context);
break;
}
return creator;
}
}
我会尝试找到一种方法来实例化 ICreator 类,避免使用简单的工厂类,我可以使用任何重构或设计模式吗? 阅读 Martin Fawler 的书,我想知道我是否可以使用多态,但我找不到任何方法在我的代码中复制它。
【问题讨论】:
-
您正在使用多态性。这对我来说看起来很干净(除了带有
I前缀的接口命名)。您可以用枚举替换您的操作字符串,并让每个枚举实例创建 StatsCreator。 -
我同意你的看法,我会应用这些改进。实际上,我的代码和我的 Simple 工厂似乎很弱并且无法修改,如果我要添加另一种类型的创建者,我会一遍又一遍地修改该方法。
-
这就是工厂的重点。但其余代码将是相同的。在某些时候,如果您想要一些新功能,您需要添加对代码的更改。只要它仅限于工厂(和新的创建者类),就可以了
标签: java design-patterns refactoring factory-pattern