有7-8个类(可调用的实现)有一些相似的行为,也就是说,这些类有一些类似的函数和类似的实现。而且所有这些类都使用了一个HashMap (仅用于读取目的),它对所有这些类都是相同的。因此,我决定创建一个包含所有类似方法的抽象超类,并将此hashMap作为静态成员。我将为这7-8个可调用的类创建子类(因此这些类也可以通过继承来调用),这样可以提高应用程序的性能。
现在我有3个问题:
1.)这个设计有什么缺陷吗?我还能进一步改进吗?
2.)是否会出现并发问题,因为它是一个三层的层次结构,可调用类位于最底层的两层?
3.)初始化静态块中的静态成员(Hashmap)是否错误?因为我的老板非常反对使用静态成员和块。那么,如果我在静态块中初始化这个map,可能会发生什么问题呢?
public abstract class AbSuper {
private static HashMap hmap;
private static CompletionService<String> service;
private static int maxThreads = 10;
static{
initializeMap();
}
public static void initializeMap(){
//load from file
}
public HashMap getmap(){
return hmap;
}
public void commonMethodOne(){
//do something
}
public static CompletionService<String> getService(){
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
service = new ExecutorCompletionService<String>(executor);
return service;
}}
public class CallableOne extends AbSuper implements Callable<String>{
private List<String[]> taskList;
protected HashMap resultMap;
public List<String[]> getTaskList(){
return taskList;
}
public String call(){
for(String[] task : getTaskList()){
getService().submit(new SubCallableOne(task));
}
return "done with Callable One";
}}
public class SubCallableOne extends CallableOne {
String[] task;
public SubCallableOne(String[] task) {
this.task = task;
}
public String call(){
//do what you are suppose to do
//and then access and populate "resultMap" fom superclass
return "done with subCallableOne";
}}
将有7-8个CallableOne/two/three以及与之对应的SubCallableOne/two/three。
发布于 2015-09-25 21:08:12
1)你真的需要使用静态成员吗?如果是这样,也许您应该将其封装在一个单独的类中,并通过封装而不是继承来使用它。我仍然会保留一个包含通用方法的超类。
但无论如何,您当前的代码都存在问题。即:
AbSuper.getMap公开地图,并且它是可变的。任何代码都可以添加、删除或覆盖条目。它真的应该公开吗?看起来只有子类在使用它。如果是这样,您可以将其设置为protected,并返回一个只读映射或副本,或者改为创建一个受保护的函数readFromMap(key)。AbSuper.getService方法也是如此:它是公共的和静态的。任何类中的任何代码都可以提交任务或关闭它。除非您每次都创建一个新的executor。这可能是一个错误,因为每次调用getService都会覆盖service变量。看起来您试图在此处实现单例,但失败了。2)可调用类可能位于底部,但由于公共静态方法,您会将基类中的功能公开给程序中的所有其他类,以及由于公共方法而持有实例的任何人。即使这些方法不存在,所有实例都使用共享的map和executor服务的事实也可能导致意外的副作用。例如,提交任务的执行顺序。
3)这本身不是错误的,但静态是众所周知的代码味道。这使得类很难测试。并且不能被重写。在纯面向对象的设计中,应该不需要静态。在您的示例中,映射将在第一次加载类时初始化,因此对AbSuper.getMap的任何调用都将填充映射。但是你的地图有两个问题。第一个问题是,这通常不适合长时间的操作,比如从文件填充地图。你应该让长操作变得明确,不要把它们隐藏在构造函数或静态初始化器中。第二,映射是可变的。
https://stackoverflow.com/questions/32414069
复制相似问题