Item 21主要讲述了在java里,用function object来表示strategy。
有些语言支持function pointers(指向函数的指针),但是java不支持。在java里,可以用object reference去达到类似的效果。
什么是function pointers
函数的指针在C++中的例子:
int foo()
{
return 5;
}
int goo()
{
return 6;
}
int main()
{
int (*funcPtr)() = foo; // funcPtr 现在指向了函数foo
funcPtr = goo; // funcPtr 现在又指向了函数goo。但是千万不要写成funcPtr = goo();这是把goo的返回值赋值给了funcPtr
return 0;
}
java里的替代
在java里,invoking a method on an object typically performs some operation on that object(对一个object调用一个method会在这个object上面进行一些操作)。但是我们也可以通过给method传入object,对其他object进行操作。
我们看看下面这个class:
class StringLengthComparator {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
这个class是stateless的:它没有fields。所以这个class的所有实例都是功能上相等的。一个StringLengthComparator的实例就是一个concrete strategy。
除了concrete strategy,我们还需要strategy interface。否则使用者不能再传入其他的comparison strategy。
// strategy interface
public interface Comparator<T> {
public int compare(T t1, T t2);
}
concrete strategy常常用anonymous classes定义,比如说:
Arrays.sort(stringArray, new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
);
如果concrete strategy会被反复用到,我们可以用private static member class定义这个concrete strategy,再把这个class当做另一个class的public static final field,定义成它的strategy interface的类型。
// exporting a concrete strategy
class Host {
private static class StrLenCmp implements Comparator<String>, Serializable {
public int compare() {
return s1.length() - s2.length();
}
}
// returned comparator is serializable
public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StrLenCmp();
... // bulk of class omitted
}
Reference
网友评论