这是反模式的一个例子吗?

时间:2017-03-03 10:43:27

标签: java design-patterns

我和我的一位同事试图解决以下问题:

让我们举一个A类的例子 我的一位同事面临从A中提取一个特定属性的问题。 从一个特定类(在这种情况下为A)中获取一个属性很容易。但是让我们 假设您有多个类(A1,A2 ...)并且您想要获取一个类 来自这些类的集合的特定属性,具有越来越多的代码可重用性。

例如

public class A {
    private String name;
    .
    .
    .
}
List<String> listOfNames = createNameList(listOfAInstances);

createNameList()方法如下:

List<String> tempList = new ArrayList<>();
for(A a : listOfAInstances) {
    tempList.add(a.getName());
}
return tempList;

现在如果有多个类,我必须为每个类和不同的属性执行此操作。

我提出了两种方法:

  1. 基于反思的方法。
  2. 创建一个名为&#34; PropertyExtractable&#34;的界面并在其中放入一个名为&#34; extractProperty&#34;在它。
  3. 如下图所示:

    interface PropertyExtractable {
        Object extractProperty();
    }
    
    public class A implements PropertyExtractable {
        private String name;
        .
        .
        .
        public Object extractProperty() {
            return this.name;
        }
    }   
    

    为此,我可以编写一些实用方法,然后可以在任何地方使用,即

        public Object getPropertiesOfPropertyExtractable(PropertyExtractable prExtractable) {
            return prExtractable.extractProperty();
        }
    

    这是背景,我的另一位同事对第二种方法有不同看法,他告诉我这似乎是反模式。他试图向我解释,但我并没有完全理解,所以我在这里问。

    我试图将此示例与Java中的Comparator接口进行比较。像java一样允许我们在任何自定义对象类上使用Comparator并允许我们定义逻辑以进行比较,那么为什么我不能定义提取逻辑

    可以通过这种方式使用更多接口,那么为什么我们不应该使用它

    我想知道这种方法是反模式吗?为什么呢?

2 个答案:

答案 0 :(得分:0)

您可以将解压缩代码放在单独的方法中并重复使用它:

class A {
    private String name;

    public String getName() {
        return name;
    }
}

class B {
    private String surname;

    public String getSurname() {
        return surname;
    }
}

public class SomeClass {

    private <T> List<String> extractFields(List<T> list, Function<T, String> extractorFunction) {
        return list.stream().map(extractorFunction).collect(Collectors.toList());
    }

    public void someMethod() {

        List<A> listOfInstancesA = new ArrayList<>();
        List<B> listOfInstancesB = new ArrayList<>();

        // fill lists

        List<String> fieldsA = extractFields(listOfInstancesA, A::getName);
        List<String> fieldsB = extractFields(listOfInstancesB, B::getSurname);
    }
}

答案 1 :(得分:0)

您描述的情况是使用您不想更改的旧系统。

因为如果您没有为公共属性引入接口(例如Comparator接口的示例)。您引入了一个没有含义的接口,这可能是一个反模式,因为您实际上需要一个功能接口:PropertyExtractable vs. NamedObject =&gt;有一个方法:String getName())。

如果你想要实现Reflection,那么你的界面可能是正确的但我没有看到它(例如在你的情况下你已经反射内置到Java)。

通常使用适配器模式从未实现所请求接口的对象获取属性/方法。