java:函数对象作为策略

时间:2011-11-03 10:23:12

标签: java oop interface function-pointers effective-java

我正在阅读Effective Java。在讨论使用函数对象作为策略的部分中,存在以下段落。

  

因为策略界面可以作为其所有具体策略的类型   实例,不需要公开具体的策略类来输出具体的   战略。相反,“主机类”可以导出公共静态字段(或静态工厂)   方法)其类型是策略接口,具体策略类可以   是主机的私有嵌套类

   // Exporting a concrete strategy
  class Host {
        private static class StrLenCmp
               implements Comparator<String>, Serializable {

        public int compare(String s1, String s2) {
            return s1.length() - s2.length();
        }
    }

    // Returned comparator is serializable
    public static final Comparator<String>
    STRING_LENGTH_COMPARATOR = new StrLenCmp();
    ... // Bulk of class omitted
  }        

我的问题是,使用上述方式有什么特别的优势吗?通过公布具体战略来导出战略有什么问题?

3 个答案:

答案 0 :(得分:2)

是的,有。这样你就可以返回接口而不是具体的类,所以如果你改变了Comparator接口的具体实现,你也不必修改客户端类(我认为这是使用接口的最重要原因)。

例如:

//inside aClass

Comparator c = Host.STRING_LENGTH_COMPARATOR; //Programming against interfaces is different from:
StrLenCmp  c = Host.STRING_LENGTH_COMPARATOR; //programming against concrete class

假设将来你将使用另一个实现(让我们称之为NewStrLenCmp)更改StrLenCmp,而不是使用针对接口Comparator进行编程而不必修改aClass。

Comparator c = Host.STRING_LENGTH_COMPARATOR; //still work because interface doesn't changed
NewStrLenCmp  c = Host.STRING_LENGTH_COMPARATOR; // problem: you need to modify the client class in order to use the new concrete type: bad idea

答案 1 :(得分:2)

与使用任何公开 - 封装相同的问题。

对象的最小可能范围使得更容易推断出如何使用该对象,并且可以大规模地简化维护(您知道private对象只能在您使用的同一源文件中使用看着,但你真的不知道有多少人使用public对象或以什么方式使用。

如果您将所有内容声明为公开,那么每个Java程序都可以正常工作。但它有点像潘多拉的盒子 - 一旦你打开了某些东西,就很难把它拿回来。

通过不公开具体策略,您可以阻止其他类/应用程序将其用于自己的目的,这意味着您不必担心将其设计为完全成熟,闪亮,稳定,公共具有明确定义的接口的类。您现在就可以编写适用于 you 的内容,并且知道您可以随意更改它。

答案 2 :(得分:2)

  • 公共内容您的API。如果您发送代码后来需要更改策略实施,那么您已经为所有发送代码的人有效​​地破坏了API。

  • 因此,除非另有要求,否则一切都应尽可能在最狭窄的范围内。

  • 我们还将它放入静态嵌套类中,因为我们没有在其他地方使用此策略。