用于将集合分成组的OO模式

时间:2012-04-09 16:39:34

标签: java oop design-patterns

我有一个MyObjects列表,我需要分成三组:

  1. 知道好(保持)
  2. 已知不好(拒绝)
  3. 无法识别(提醒警报)
  4. MyObject包含各种属性,必须检查这些属性以确定将对象放入的3个组中的哪个组。

    我的初始实现(Java)只是在其构造函数中使用List并在那里进行分类。伪代码:

    class MyObjectFilterer {
      public MyObjectFilterer(List<MyObject> list) {
        // triage items here
      }
      public List<MyObject> getGood() {
        // return sub-list of good items
      }
      public List<MyObject> getBad() {
        // return sub-list of bad items
      }
      public List<MyObject> getUnrecognized() {
        // return sub-list of unrecognized items
      }
    }
    

    此实施有任何问题吗?是否有更好的OO选择?

5 个答案:

答案 0 :(得分:2)

我可能更喜欢静态工厂方法来进行过滤,然后调用一个私有构造函数来获取三个过滤后的列表,遵循从不在构造函数中做任何认真工作的良好代码实践。除此之外,这看起来很好。

答案 1 :(得分:0)

可能有多种方法。如果问题足够通用/重复,您可以使用方法定义一个接口来对对象进行分类。

interface Selector {
  public boolean isGood(MyObject myObject);
  public boolean isBad(MyObject myObject);
  public boolean isUnknown(MyObject myObject);

}

这样你就可以轻松改变逻辑实现。

答案 2 :(得分:0)

另一个想法是使用责任链。

您的 MyObjectFilterer 包含对三个对象 GoodFilterer BadFilterer UnrecognizedFilterer 的引用。它们中的每一个都包含以下方法: addMethod(MyObject对象) getObjects() addFilter()。当然,他们必须实现一个界面 Filterer

使用 addFilter 方法,您可以构建链。以便 GoodFilterer 包含对 BadFilterer 的引用,并且此引用包含对 UnrecognizedFilterer

的引用

现在,您将浏览 MyObjects 列表,并在 GoodFilterer (此链中的第一个)上调用add方法。在add方法中,您决定这是否合适,而不是保留它并完成工作,如果没有将其传递给 BadFilterer

你保留了三种获取好/坏和无法识别的方法,但是你会将它传递给相应的 Filterer

getObjects()方法

好处是,如果这是好的/坏的或无法识别的逻辑现在是分开的。

在下方,你需要3个新类和1个接口。

但就像我说的那样,这只是你可以做的另一个想法。

答案 3 :(得分:0)

你应该尽可能简化。只需使用以下签名在MyObjectFilter中创建静态方法:

public static List filterMyObjects(List data,Group group)。

Group是具有三个值的枚举,可以用作MyObject类的属性

答案 4 :(得分:0)

我可能会尝试类似的事情:

enum MyObjectStatus {
   GOOD, BAD, UNRECOGNIZED;
}

class MyObjectFilterer {
  private MyObjectStatus getStatus(MyObject obj) {
    // classify logic here, returns appropriate enum value
  }

  // ListMultimap return type below is from Google Guava
  public ListMultimap<MyObjectStatus, MyObject> classify(List<MyObject> objects) {
     ListMultimap<MyObjectStatus, MyObject> map = ArrayListMultimap.create();
     for(MyObject obj: objects) {
        map.put(getStatus(obj), obj);
     }
  }
}

调用classify()获取Multimap,并根据需要提取每个类别:

List<MyObject> good = map.get(GOOD);
List<MyObject> bad = map.get(BAD);
List<MyObject> unknown = map.get(UNRECOGNIZED);

这个解决方案的一个好处是你不必为每个类别创建/发布访问器方法(除非你想要),如果创建了新的类别,你也不会添加新的访问者 - 只是新枚举和附加分类器逻辑。