【问题标题】:Refactoring Java class with multiple responsibilities重构具有多种职责的 Java 类
【发布时间】:2014-01-23 14:37:22
【问题描述】:
public class MyObject
{
    public static enum Type {A, B, C, D;}

    public static final int ID_MAIN = 1;
    public static final int ID_MAIN_UK = 2;
    public static final int ID_MAIN_US = 3;
    public static final int ID_SUB = 4;
    // lots more constants here

    public static final String DESCRIPTION_1 = "Desc Full Name";
    public static final String DESCRIPTION_2 = "Desc2 Full Name";
    // lots more constants here

    private int id;

    public MyObject(final int id)
    {
        this.id = id;
    }

    //simple getter 
    public int getID() { return this.id;}

    // real responsibility of the class is in the following two methods
    public static String getDescription()
    {
         switch(id)
         {
              case MyObject.ID_MAIN:
              case MyObject.ID_MAIN_UK:
                  return MyObject.DESCRIPTION_1;
              case MyObject.ID_SUB:
                  return MyObject_Description_2;
              default:
                   // throw IllegalArgException
          }        
     }

     public static Type getType(int id)
     {
         switch(id)
         {
             case MyObject.ID_MAIN:
             case MyObject.ID_SUB:
                 return Type.A;
             case MyObject.ID_MAIN_UK:
             case MyObject.ID_MAIN_US:
                 return Type.B;
             default:
                 return Type.Undefined;
         }
      }
 }

基本上,有一个 ID 映射到描述和类型。这个 ID 在类的构建过程中被传入,它应该映射到类中已经包含的一组常量。如果 id 不是常量列表的一部分,则在尝试获取映射到 id 的描述时会引发错误,如果查询类型,则会返回“未知”类型。 ID 将描述映射到一组常量。相同的 ID 映射到某个 Type(定义为枚举)。

这段代码非常难看,因为在顶部定义了大量的常量,这使得 switch 语句非常臃肿。有没有一种简单的方法可以在不更改公共接口的情况下对其进行重构?它看起来很简单,但不管你怎么切,它看起来都很难看。如何简化这些映射以使代码更简洁?

我正在考虑在一个文本文件中表示映射,并有一个管理器类在哈希图中保存简单的容器。构造管理器类时,它将通过读取文本文件来创建对象并将它们映射到一个 ID。当通过 ID 查询 manager 时,它会调用相应的 get 方法,例如:

class Manager 
{
     private HashMap<int, MyObject> objectMap;

     public Manager() {} //construct the object map
     public String getDescription(int id) { return objectMap.get(id).getDescription();}
     public Type getType(int id) { return objectMap.get(id).getType();}
}

class DataContainer
{
     private String description;
     private Type type;


     public DataContainer(String desc, Type type) {//set mem vars}
     public String getDescription() //simple getter
     public Type getType() //simple getter
 }

但是这个解决方案似乎太复杂了。有没有更好的解决方案,最好是将所有东西都放在一个类中?

【问题讨论】:

  • 这个答案可能更适合codereview.stackexchange.com
  • 这个问题似乎离题了,因为它是关于代码审查的,应该重定向到 codereview.stackexchange.com
  • @mdewitt:OP 显然不要求 CR。代码审查从作者认为接近完美的代码开始。这里作者问的是如何解决一个具体问题,代码只是一个说明。

标签: java refactoring


【解决方案1】:

您可以执行以下操作。这样会更干净、更易于管理。

public enum Type
{

    MAIN(1, "Main Description"),
    MAIN_UK(2, "Main UK Description"),
    //....
    //Define all the types
    //....
    UNKNOWN(-1, "Unknown Type");

    private int id;
    private String description;

    private Type(int id, String description)
    {
        this.id = id;
        this.description = description;
    }

    public static Type getById(int id)
    {
        for (Type type : Type.values())
        {
            if (id == type.getId())
            {
                return type;
            }
        }

        return Type.UNKNOWN;
    }

    public final int getId()
    {
        return id;
    }

    public final String getDescription()
    {
        return description;
    }
}

public class MyObject
{
    private int id;
    private Type type;

    public MyObject(int id)
    {
        this.id = id;
        this.type = Type.getById(id);
    }

    public int getId()
    {
        return id;
    }

    public Type getType()
    {
        return type;
    }

    public String getDescription()
    {
        return type.getDescription();
    }
}

【讨论】:

    【解决方案2】:

    在 Java 中枚举可以有方法。例如下面的一个接受 ID 和描述并提供一些访问器。

    public enum Type {
            MAIN(1, "desc1"),
            UK(2, "desc2"),
            SUB(4, "desc4");
    
            private int id;
            private String desc;
    
            Type(int id, String desc) {
                this.id = id;
                this.desc = desc;
            }
            public String getDescription() {
                 return  desc;
            }
    
            public int getType() {
                //return id;
                return 1+2 + 3+ id;
            }
        }
    

    您可以使用它来改进设计。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多