1

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

  1. 已知良好(保留)
  2. 已知不良(拒绝)
  3. 无法识别(提高警报)

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

4

5 回答 5

2

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

于 2012-04-09T16:42:18.417 回答
0

可能有多种方法。如果问题足够普遍/重复,您可以定义一个带有分类对象的方法的接口。

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

}

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

于 2012-04-09T16:46:15.263 回答
0

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

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

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

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

您保留用于获取好/坏和无法识别的三种方法,但您会将其传递给相应过滤器的getObjects ()方法

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

缺点是您需要 3 个新类和 1 个接口。

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

于 2012-04-09T17:03:09.943 回答
0

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

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

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

于 2012-04-09T17:14:03.393 回答
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);

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

于 2012-04-09T17:39:51.020 回答