ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

跟我学(Effective Java 2)第21条:用函数对象表示策略

2019-06-05 18:51:43  阅读:213  来源: 互联网

标签:跟我学 Java 21 Comparator StringLengthComparator 函数 接口 public 策略


第21条:用函数对象表示策略

有些语言支持函数指针(function pointer)、代理(delegate)、lambda表达式(lambda expression),或者支持类似的机制,允许程序把“调用特殊函数的能力”存储起来并传递这种能力。这种机制通常用于允许函数的调用者通过传入第二个函数,来指定自己的行为。

C语言标准库中的qsort函数要求用一个指向comparator函数的指针作为参数,它用这个函数来比较待排序的元素。比较器有两个参数,都是指向元素的指针。通过传递不同的比较器函数,可以获得不同的排列顺序,这是策略模式的一个例子。比较器函数代表一种为元素排序的策略。

什么是策略模式?策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

public class StringLengthComparator {
    private StringLengthComparator() {
    }

    public static final StringLengthComparator INSTANCE = new StringLengthComparator();

    public int compare(String str1,String str2){
        return str1.length() - str2.length();
    }
    //以上内容用静态单例模式 执行策略 灵活性低。所以设计策略模式时,还要定义一个策略接口。而实现时往往采用匿名内部类来实现。

}

为了把StringLengthComparator实例传递给方法,需要适当的参数类型。使用StringLengthComparator并不好,因为客户端将无法传递任何其他的比较策略。相反,我们要定义一个Comparator接口,并修改StringLengthComparator来实现这个接口。换句话说,我们在设计具体的策略类时,还需要定义一个策略接口(strategy interface),如下所示:

public interface Comparator<T> {
     public int compare(T t1,T t2);
 }

因为策略接口被用作所有具体策略实例的类型,所以我们并不需要为了导出具体策略,而把具体策略做成公有的。相反,“宿主类(host class)”还可以导出公有的静态域(或者静态工厂方法),其类型为策略接口,具体的策略接口类可以是宿主类的私有嵌套类。下面的例子使用静态成员类,而不是匿名类,以便允许具体的策略类实现第二个接口Serializable:

//已Comparator为策略接口 静态内部类为实现,可以用于多实现 ,如序列化
class Host{
    private static class StrLenCmp implements Comparator<String>, Serializable{
        @Override
        public int compare(String o1, String o2) {
            return o1.length() - o2.length();
        }
    }

    public static final Comparator<String> STRING_COMPARATOR_LENGTH= new StrLenCmp();
}

简而言之,函数指针的主要用途就是实现策略(strategy)模式。为了在Java中实现这种模式,要声明一个接口来表示该策略,并且为每个具体策略声明一个实现了该接口的类。当一个具体策略只被使用一次时,通常使用匿名类来声明和实例化这个具体策略模类。当一个具体策略是设计用来重复使用的时候,它的类通常就要被实现为私有的静态成员类,并通过公有的静态final域被导出,其类型为该策略接口。

标签:跟我学,Java,21,Comparator,StringLengthComparator,函数,接口,public,策略
来源: https://blog.csdn.net/Dullon_jiang/article/details/90913852

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有