用于在类之间切换的设计模式

时间:2014-03-28 15:26:25

标签: design-patterns

假设我有这四个类:

class A {
  int i; 
}
class B { 
  int i; 
  bool b;
}
class C { 
  int i;
  enum e; 
}
class D { 
  int i;
  float f;
}

我想在数据网格中显示类的属性。像这样:

+----+------+---+---+-------+-----+
| id | type | i | b |   e   |  f  |
+----+------+---+---+-------+-----+
|  1 |   A  | 1 |   |       |     |
|  2 |   C  | 3 |   | Enum1 |     |
|  3 |   A  | 4 |   |       |     |
|  4 |   D  | 1 |   |       | 2.5 |
+----+------+---+---+-------+-----+

'type'列的单元格必须是一个下拉菜单,因此类型可以切换到另一种类型。

解决这个问题的好设计模式是什么?

当然我有一些想法(但我不知道哪个是最好的): 从超类S中导出A,B,C和D?在S中用TypeA,TypeB,TypeC,TypeD创建一个枚举“Type”,这样我可以将它用于列'type'吗?

我可以做一个组合:而不是从超类派生, E类包含接口I. A,B,C和D实现I. E再次枚举'Type',所以当我切换enum-value时,接口I成为另一个类的对象。 或者我应该跳过这个枚举,让列'type'代表直接连接到接口I的类?

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

多态性可以在这里应用。我们可以考虑两个继承层次结构 - 一个用于类类型信息,另一个用于实际类。具有类型信息的类可以实现为单例,因为它对于所有实例都是相同的。

当数据显示在网格中时,此设计可以无缝处理所有类。

为简单起见,示例代码仅显示了一个B类的实现。

interface ClassInfo {
    String getClassType();
    ArrayList<String> getPropertyNames();
    boolean hasProperty(String propertyName);
}

class BClassInfo implements ClassInfo {

    static ArrayList<String> propertyNames = new ArrayList<String>();
    private static BClassInfo instance = null;

    private BClassInfo() {
        propertyNames.add("i");
        propertyNames.add("b");
    }

    static public ClassInfo getInstance() {
        if (instance == null) {
            instance = new BClassInfo();
        }

        return instance;
    }

    @Override
    public String getClassType() {
        return "B";
    }

    @Override
    public ArrayList<String> getPropertyNames() {
        return propertyNames;
    }

    @Override
    public boolean hasProperty(String propertyName) {
        return (propertyName.equals("i") || propertyName.equals("b"));
    }
}

abstract class SuperClass {
    public ClassInfo classInfo;

    abstract public String getValue(String propertyName);
}

class B extends SuperClass {
    int i;
    boolean b;

    public B() {
        classInfo = BClassInfo.getInstance();
    }

    @Override
    public String getValue(String propertyName) {
        if (propertyName.equals("i") == true) {
            return Integer.toString(i);
        } else if (propertyName.equals("b") == true) {
            return Boolean.toString(b);
        }

        return "";
    }
}

public class Test {

    public static void main(String[] args) {
        B bClass = new B();
        // instances of other classes are created.

        ArrayList<String> bClassProperties = bClass.classInfo.getPropertyNames();
        // collect properties of other classes.

        HashSet<String> propertySet = new HashSet<String>();
        // Now put all the properties in a set so that duplicates are removed.

        ArrayList<SuperClass> data = new ArrayList<SuperClass>(); // data to display in the grid.

        // Display the column headers (property set values from propertySet)

        for (SuperClass superClass : data) {
            // display type of class from superClass.classInfo.getClassType()
            for (String propertyName : propertySet) {
                if (superClass.classInfo.hasProperty(propertyName) == true) {
                    // display value of property from superClass.getValue(propertyName);
                }
            }
        }
    }

}