首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >面向对象设计与Asbtract超类中静态成员的初始化

面向对象设计与Asbtract超类中静态成员的初始化
EN

Stack Overflow用户
提问于 2015-09-05 22:15:25
回答 1查看 45关注 0票数 0

有7-8个类(可调用的实现)有一些相似的行为,也就是说,这些类有一些类似的函数和类似的实现。而且所有这些类都使用了一个HashMap (仅用于读取目的),它对所有这些类都是相同的。因此,我决定创建一个包含所有类似方法的抽象超类,并将此hashMap作为静态成员。我将为这7-8个可调用的类创建子类(因此这些类也可以通过继承来调用),这样可以提高应用程序的性能。

现在我有3个问题:

1.)这个设计有什么缺陷吗?我还能进一步改进吗?

2.)是否会出现并发问题,因为它是一个三层的层次结构,可调用类位于最底层的两层?

3.)初始化静态块中的静态成员(Hashmap)是否错误?因为我的老板非常反对使用静态成员和块。那么,如果我在静态块中初始化这个map,可能会发生什么问题呢?

代码语言:javascript
复制
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;
}

}

代码语言:javascript
复制
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";
}

}

代码语言:javascript
复制
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。

EN

回答 1

Stack Overflow用户

发布于 2015-09-25 21:08:12

1)你真的需要使用静态成员吗?如果是这样,也许您应该将其封装在一个单独的类中,并通过封装而不是继承来使用它。我仍然会保留一个包含通用方法的超类。

但无论如何,您当前的代码都存在问题。即:

  • 您正在通过公共方法AbSuper.getMap公开地图,并且它是可变的。任何代码都可以添加、删除或覆盖条目。它真的应该公开吗?看起来只有子类在使用它。如果是这样,您可以将其设置为protected,并返回一个只读映射或副本,或者改为创建一个受保护的函数readFromMap(key)
  • AbSuper.getService方法也是如此:它是公共的和静态的。任何类中的任何代码都可以提交任务或关闭它。除非您每次都创建一个新的executor。这可能是一个错误,因为每次调用getService都会覆盖service变量。看起来您试图在此处实现单例,但失败了。

2)可调用类可能位于底部,但由于公共静态方法,您会将基类中的功能公开给程序中的所有其他类,以及由于公共方法而持有实例的任何人。即使这些方法不存在,所有实例都使用共享的map和executor服务的事实也可能导致意外的副作用。例如,提交任务的执行顺序。

3)这本身不是错误的,但静态是众所周知的代码味道。这使得类很难测试。并且不能被重写。在纯面向对象的设计中,应该不需要静态。在您的示例中,映射将在第一次加载类时初始化,因此对AbSuper.getMap的任何调用都将填充映射。但是你的地图有两个问题。第一个问题是,这通常不适合长时间的操作,比如从文件填充地图。你应该让长操作变得明确,不要把它们隐藏在构造函数或静态初始化器中。第二,映射是可变的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32414069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档