【问题标题】:Design Pattern Need to remove a series of If.. elses in object initialization设计模式需要去掉对象初始化中的一系列If..else
【发布时间】:2011-08-04 19:15:54
【问题描述】:

我正在编写一个应用程序,其中有多个部门,每个部门都有单独的处理类。 每个部门和部门处理由单独的类表示。

所以,现在 java 中的 main 方法看起来更像是一系列 if else 阶梯。

有没有什么办法让它更灵活,这样我以后就可以添加更多的部门和他们的处理类,而不需要对原来写的类做太多修改??

我读过关于抽象工厂模式的文章,但除了它还有其他解决方案吗??

【问题讨论】:

  • 我不明白人们是如何回答这个问题的。你的问题不是很清楚,考虑改写。发布一个您当前拥有的“愚蠢”示例可能会有所帮助。
  • 您是否发现使用抽象工厂模式存在问题?
  • 好吧,没有问题,但我只是想在实际实施之前考虑所有可能的选择。

标签: java design-patterns abstract-factory


【解决方案1】:

创建一个界面来隐藏部门,例如“部门”。编写你的主要方法:

main() {
    String criteria = ...; // this is how we choose the department to use,
                           // and you probably don't want to use a String
                           // but some other, more expressive type
    for (Department department : departments) {
        if (department.supports(criteria)) {
            department.doWhatever();
        }
    }
}

然后使用依赖注入来填充departments 集合。根据您的设置方式,它可能是纯配置。

【讨论】:

  • 使用字符串封装一些可能很复杂并且应该在它自己的类中的东西......这似乎不是一个很好的做法。
  • @Atreys:我同意。 main 方法也应该接受一个 String[] 参数。这只是一个例子。添加到代码示例中以使其明确。
【解决方案2】:

抽象工厂模式可能最适合您描述的场景。您将需要部门处理器的层次结构和部门类的匹配层次结构。抽象工厂将根据一些判别器为每一对生成一个具体工厂,为您处理部门并返回部门对象。

您的应用程序的其余部分不需要了解部门对象的创建差异,因为它会使用工厂来获取部门,只需通过适当的鉴别器即可。

添加新部门将需要新部门类、处理器类和更新工厂逻辑。


或者,如果部门的结构都相同但处理方式不同,您可以考虑使用类似战略模式的东西。在这种情况下,您只有一个部门,但有关处理的决定将由战略来代替。所以给部门注入了合适的Strategy,部门的行为也随之不同。

【讨论】:

    【解决方案3】:

    有一个专门讨论该主题的网站。您想使用多态性和可能的​​反射,具体取决于您要执行的操作。

    http://www.antiifcampaign.com/

    【讨论】:

      【解决方案4】:

      您可以为每个州创建带有字段的枚举。然后在枚举中创建抽象方法init(),并为每个成员实现。

      在您的代码中,您可以从例如属性文件中获取状态,然后说State.valueOf(state).init()

      【讨论】:

      • 我们是否允许在枚举中也有抽象方法??
      • 一个枚举可以有抽象方法并实现一个接口,但是每个枚举值都必须实现它。
      【解决方案5】:

      使用“工厂”或“抽象工厂”设计模式将是第一步。这会将对象初始化逻辑从您的主代码中取出,并将其隔离在工厂类中。这样,您的主代码将关闭以进行修改并打开以进行扩展(又名Open Closed Principle)。您所做的更改将被隔离在工厂类中。

      如果您想更进一步,您也可以使用反射。一个例子是:

      static Object createObject(String className) {
        Object object = null;
        try {
            Class classDefinition = Class.forName(className);
            object = classDefinition.newInstance();
        } catch (InstantiationException e) {
            System.out.println(e);
        } catch (IllegalAccessException e) {
            System.out.println(e);
        } catch (ClassNotFoundException e) {
            System.out.println(e);
        }
        return object;
      }
      

      使用此代码,您可以像这样简单地创建一个对象:

      public static void main(String[] args) {
          NewDepartment dep = (NewDepartment) createObject("yourpackage.NewDepartment");
      }
      

      当然,使用反射时有trade-off。使用与否由您自行决定。

      【讨论】:

        猜你喜欢
        • 2016-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多