【问题标题】:java : Function objects as strategiesjava:作为策略的函数对象
【发布时间】:2011-12-21 01:15:10
【问题描述】:

我正在阅读有效的 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
  }        

我的问题是,使用上述方式有什么特别的好处吗?通过公开具体策略来导出策略有什么问题?

【问题讨论】:

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


    【解决方案1】:

    是的,有。这样您返回的是接口而不是具体类,因此如果您更改 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
    

    【讨论】:

      【解决方案2】:

      这与将 anything 公开 - 封装的问题相同。

      对象的最窄范围可以更轻松地推断该对象的使用方式,并且可以大大简化维护(您知道private 对象只能在您正在查看的同一源文件中使用,但您永远无法真正知道有多少人在使用public 对象或以何种方式使用)。

      如果您将所有内容都声明为公开,那么每个 Java 程序都可以运行,当然。但这有点像潘多拉的盒子——一旦你打开了对某些东西的访问权限,就很难收回它。

      通过不公开具体策略,您可以防止其他类/应用程序将其用于自己的目的,这意味着您不必担心将其设计为成熟、闪亮、稳定、公开的具有良好定义接口的类。您可以立即编写适合您的内容,并且知道您以后可以随意更改它。

      【讨论】:

        【解决方案3】:
        • 公共的东西是你的 API。如果您交付代码后需要更改您的策略实施,那么您实际上已经破坏了您向其交付代码的每个人的 API。

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-12-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多