【问题标题】:Proper design pattern for passing flags to an object将标志传递给对象的正确设计模式
【发布时间】:2012-07-20 15:08:45
【问题描述】:

在 C 中我做过这种事情

enum { USE_COKE = 1,
        USE_PEPSI = 2,
        USE_JUICE = 4,
        USE_WATER = 8 };

 int makeDrink(int flags);

 //...

 int rcode = makeDrink(USE_COKE | USE_JUICE | USE_WATER);

我知道这是非常标准的,例如iostream 也使用它。我想知道如何将这种设计模式翻译成 Java 或 OOP?我相当确定多态不是这里的方法,因为我的代码有一个if(flag_is_set) 块比重写大部分例程更好。是否有一个实用程序 Flags 类,或者使用配置对象、enum 或一堆整数等的首选方法。

【问题讨论】:

  • 你不需要Java中的标志,只需使用EnumSet

标签: java oop design-patterns enum-flags


【解决方案1】:

Java 有枚举。这是tutorial

我会在整数等上使用这些。这是一种类型安全的解决方案,并且由于枚举是对象,因此您可以附加行为并避免使用 switch 语句。

您可以使用EnumSet 组合这些(如上)。来自文档:

用于枚举类型的专用 Set 实现 .... 这个 表示非常紧凑和高效。空间和时间 此类的性能应该足够好,以允许其用作 高质量、类型安全的替代传统基于 int 的“位” 标志。”

【讨论】:

    【解决方案2】:

    Answer by Brian Agnew 是正确的。 Java 有一个强大、灵活且非常方便的Enum 工具。 (不要与现在已经过时的Enumeration 界面混淆。)

    示例代码

    这是基于问题的示例代码。

    public enum Liquid {
        COKE, PEPSI, JUICE, WATER
    }
    

    采用该枚举类型的EnumSet 的方法。

    public Drink makeDrink ( EnumSet<Liquid> ingredients ) {
        System.out.println ( "ingredients: " + ingredients );
        if ( ingredients.contains ( Liquid.JUICE ) ) {
            // Treat as a Collection. 
            // `EnumSet` is just another `Set` implementation, though a very fast one.
        }
        for ( Liquid ingredient : ingredients ) {
            // Access each item in the collection, each Liquid object in the EnumSet.
        }
    }
    

    调用该方法的代码,实例化并传递必要的EnumSet

    EnumSet ingredients = EnumSet.of ( Liquid.COKE , Liquid.JUICE , Liquid.WATER );
    Drink drink = this.makeDrink ( ingredients );
    

    运行时。

    成分:[可乐、果汁、水]

    请记住,这些是真实的对象、类型安全的、编译器强制执行的、静态定义的和自记录的。不要将它们误认为仅仅是字符串。

    【讨论】:

      【解决方案3】:

      您还拥有Java EnumMap,因此您可以在将它们的总和传递给您的方法之前,从您的饮料所需的所有USE_XXX 中的EnumMap 中获取值

      【讨论】:

        【解决方案4】:

        有多个选项可以实现这一点。

        • 我个人喜欢 C 风格的位操作方式,它只是创建一个枚举或一组最终静态变量。
        • Java 中的另一个选项是使用java.util.BitSet 对象。
        • 从真正的 OOP 视图来看,最简洁的方法可能是实现一个带有布尔 getter/setter 的实用程序类。然后将该实用程序类传递给需要使用标志的对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-29
          • 1970-01-01
          • 1970-01-01
          • 2013-03-23
          • 1970-01-01
          • 1970-01-01
          • 2010-12-04
          • 1970-01-01
          相关资源
          最近更新 更多