用于将集合划分为组的 OO 模式



我有一个MyObjects列表,我需要将其分为三组:

  1. 已知良好(保持)
  2. 已知错误(拒绝)
  3. 无法识别(引发警报)

MyObject 包含各种属性,必须检查这些属性以确定要将对象放入 3 组中的哪一组。

我的初始实现(Java)只是在其构造函数中获取一个列表并在那里进行分类。伪代码:

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选择?

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

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

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

}

这样,您就可以轻松更改逻辑实现。

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

您的 MyObjectFilterer 包含对三个对象 GoodFilterer、BadFiltererUnrecognizedFilter er 的引用。 它们中的每一个都包含以下方法:addMethod(MyObject object)、getObjects()addFilter()。当然,他们必须实现一个接口过滤器

使用 addFilter 方法,您可以构建链。 以便 GoodFilterer 包含对 BadFilterer 的引用,而这个包含对 UnrecognizedFilterer 的引用

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

你保留了获取好/坏和无法识别的三种方法,但你会把它传递给相应过滤器getObjects() 方法。

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

缺点是您需要 3 个新类和 1 个界面。

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

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

公共静态列表过滤器MyObjects(列表数据,组组)。

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

我可能会尝试如下:

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);

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

最新更新