【问题标题】:Design pattern for switching between classes类之间切换的设计模式
【发布时间】:2014-03-28 15:26:24
【问题描述】:

假设我有这 4 个类:

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 |
+----+------+---+---+-------+-----+

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

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

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

我可以做一个组合,而不是从超类派生: 类 E 包含一个接口 I。A、B、C 和 D 实现 I。E 再次具有枚举“类型”,所以当我切换枚举值时,接口 I 成为另一个类的对象。 或者我应该跳过这个枚举,让列'type'代表直接附加到接口的类吗?

有什么想法吗?

【问题讨论】:

  • 这取决于您的DataGrid 的要求。如果您不需要每一行都包含所有列,那么您可以考虑使用 presenter 类(使用PresenterForAPresenterForB 等)。它将公开一个方法GetValueName()(它将返回列名)和一个方法GetValue()(它将返回值本身,如string)。它甚至可能是通过多重继承实现的接口(非常类似于通用基类,但意图更清晰,IMO)。
  • @Adriano 好,作为答案发布!
  • @MikeStockdale 它应该被详细阐述为一个答案,到目前为止,这只是我的观点的一个断言,但没有赞成/反对的讨论和/或例子!

标签: design-patterns


【解决方案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);
                }
            }
        }
    }

}

【讨论】:

    猜你喜欢
    • 2016-09-23
    • 2012-10-20
    • 2012-03-28
    • 1970-01-01
    • 2020-05-26
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多