【Effective Java】条21:使用函数对象代表策略

一些编程语言通过提供函数指针、委托、lambda表达式或者其他类似的方式,来使得程序拥有存储、并传递特殊函数的能力。Java没有提供函数指针,但是对象引用能提供相同的效果,另Java 1.8开始,提供了lambda表达式。

例如,针对字符串的比较,假设我们定义一个比较:

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

但是对于调用此比较的方法来说,也许它还需要调用其他字符串比较,那我们最好让比较实现某个接口。这样调用的方法中参数类型只需指定为接口类型即可。譬如:

class StringLengthCompare implements Comparator<String> {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
}

当需要调用比较对象(函数指针)的时候,如果只是单次调用,那么我们可以采用匿名类的形式调用,譬如:

Collections.sort(list, new Comparator<String> {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
});

但是如果是需要重复调用此比较对象,那么最好为此提供实例,避免创建多余的对象:

clas Host {
    private static class StringLengthCompare implements Comparator<String> {
        @Override
        public int compare(String s1, String s2) {
            return s1.length() - s2.length();
        }
    }

    public static final Comparator<String> STRING_LENGTH_COMPARE = new StringLengthCompare();

    //之后可以多次调用STRING_LENGTH_COMPARE对象
}

总之,函数指针的主要作用就是实现策略模式。为了实现此模式,你可以先定义个接口,之后实现接口以实现不同的具体策略。如果此策略只使用一次,采用匿名类即可;如果需要使用多次,则可以将策略作为宿主类(如上面例子中的Host类)的静态内部类,并创建静态实例供多次调用。

猜你喜欢

转载自blog.csdn.net/xl890727/article/details/80347755