- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试替换简单工厂 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/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!