gpt4 book ai didi

java - 使用多态替换简单工厂

转载 作者:行者123 更新时间:2023-12-02 04:36:40 27 4
gpt4 key购买 nike

我正在尝试替换简单工厂 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 的书,我想知道是否可以使用多态性,但我找不到任何方法在我的代码中复制它。

最佳答案

我首先尝试修改 IStatsCreator 和 AbstractStatsCreator 以拥有无状态 bean。

在您的示例中,您只需删除 AbstractStatsCreator 中定义为类变量的 StatsContext 上下文即可。因此上下文不应该绑定(bind)到类实例。当创建者调用需要上下文的方法时,应该从外部传入它。为此,您可以重构 IStatsCreator 并将上下文添加到需要它的所有方法中。

例如:

public IChart createChart() 抛出 IOException;

新:

public IChart createChart( StatsContext context ) 抛出 IOException;

等等。之后,您不必为每个上下文调用创建 AbstractStatsCreator 实现的新实例。您只需要每种类型都有一个实例。该类型的实例可以在 StatsCreatorFactory 中映射,并在需要时获取。我还建议摆脱静态方法。让 StatsCreatorFactory 成为一个真正的 bean,更容易管理,也更容易被模拟测试。:

public class StatsCreatorFactory {

private Map<String, IStatsCreator> statsCreators = new HashMap<String, IStatsCreator>();

public void registerStatsCreator( String type, IStatsCreator creator ) {
statsCreators.put( type, creator );
}

public IStatsCreator getCreator( String type ){

IStatsCreator creator= statsCreators.get( type );

if(creator == null){
throw new IllegalArgumentException("no creator registered for type : " + type);
}

return creator;
}

}

最后,StatsCreatorFactory 更像是一个提供者,而不是一个工厂。也许您也可以将其重命名为 StatsCreatorProvider。

public class StatsServlet extneds HttpServlet{

private static final long serialVersionUID = 1L;

private StatsCreatorProvider statsCreatorProvider;

public void init() {
statsCreatorProvider = new StatsCreatorProvider();
statsCreatorProvider.registerStatsCreator( "validate", new ValidateStatsCreator() );
statsCreatorProvider.registerStatsCreator( "extract" new ExtractStatsCreator() );
...
}

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

StatsContext context = new StatsContext(request,response);
IStatsCreator creator = statsCreatorProvider.getCreator( context.getOperation() );
IChart chart = creator.createChart( context );
String jsonChart = creator.chartToJson(chart);
creator.sendResponse(jsonChart);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}

}

关于java - 使用多态替换简单工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30662770/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com