这个名词不太懂,先看一个例子
import java.util.Arrays;
class Processor {//Processor是一个类
public String name() {
return getClass().getSimpleName();//返回源代码中基础类的简单名称,如果是匿名内部内返回空字符串
}
Object process(Object input) { return input; }//返回类型是Object,Object是所有类的基类,下面会有协同返回类型
}
class Upcase extends Processor {
String process(Object input) {//协同返回类型
return ((String)input).toUpperCase();//强转(向下转型)为String然后再转为小写
}
}
class Downcase extends Processor {
String process(Object input) {//协同返回类型
return ((String)input).toLowerCase();
}
}
class Splitter extends Processor {
String process(Object input) {//协同返回类型
//强转(向下转型)为String然后再用空格拆分为数组,再把数组转为字符串形式
return Arrays.toString(((String)input).split(" "));
}
}
public class Apply {
//这里接收的参数是Processor
public static void process(Processor p, Object s) {
System.out.println("Using Processor " + p.name());
System.out.println(p.process(s));
}
public static String s = "this is a test";
public static void main(String[] args) {
//传递的参数都是导出类
process(new Upcase(), s);
process(new Downcase(), s);
process(new Splitter(), s);
}
}
输出结果
Using Processor Upcase
THIS IS A TEST
Using Processor Downcase
this is a test
Using Processor Splitter
[this, is, a, test]
可以看出Apply.process()可以接受Processor的导出类,并应用到Object对象上,然后打印结果。这种创建一个内购根据所传递参数队形的不同而具有不同行为的方法,被称为
策略模式设计。这类方法包含所有执行的算法中固定不变的部分,而“策略”包含变化的部分。
用起来特别方便,如果想增加一个类似功能直接在写一个Processor的导出类即可。貌似和耦合没什么关系,继续看
public class Filter {
public String name() {
return getClass().getSimpleName();
}
Object process(Object input) { return input; }
}
这里有一个类Filter它的内容和Processor中是一模一样的,然后执行以下操作的话会提示错误
process(new Filter(), s);//The method process(Processor, Object) in the type Apply is not applicable for the arguments (Filter, String)
确实这个Filter和Processor是两个不同的类,这样调用会报参数对应的错,但是如果这样可以的话岂不是特别方便。这样不可以的原因是因为Apply.process和Processor之间耦合太紧,用接口可以达到想要的效果
import java.util.Arrays;
interface Processor {//接口实现
public String name();
Object process(Object input);
}
abstract class StringProfessor implements Processor {
public String name() {
return getClass().getSimpleName();
}
public abstract Object process(Object input);
}
class Upcase extends StringProfessor {
public String process(Object input) {//协同返回类型
return ((String)input).toUpperCase();//强转(向下转型)为String然后再转为小写
}
}
class Downcase extends StringProfessor {
public String process(Object input) {//协同返回类型
return ((String)input).toLowerCase();
}
}
class Splitter extends StringProfessor {
public String process(Object input) {//协同返回类型
//强转(向下转型)为String然后再用空格拆分为数组,再把数组转为字符串形式
return Arrays.toString(((String)input).split(" "));
}
}
public class Apply {
//这里接收的参数是Processor
public static void process(Processor p, Object s) {
System.out.println("Using Processor " + p.name());
System.out.println(p.process(s));
}
public static String s = "this is a test";
public static void main(String[] args) {
//传递的参数都是导出类
process(new Upcase(), s);
process(new Downcase(), s);
process(new Splitter(), s);
}
}
这里变化的是Processor变成了一个接口,然后再用一个(抽象)类StringProfessor实现了这个接口,Upcase也改成了继承StringProfessor这个类。如果要实现Filter的话,也实现一下这个接口即可
public class Filter{
public String name() {
return getClass().getSimpleName();
}
Object process(Object input) { return input; }
}
class FilterAdapter implements Processor {
Filter filter;//代理
public FilterAdapter(Filter filter) {
this.filter = filter;
}
public String name() {
return filter.name();
}
public Object process(Object input) {
return filter.process(input);
}
}
class LowPass extends Filter {
public String process(Object input) {//协同返回类型
return "LowPass: " + ((String)input).toLowerCase();//强转(向下转型)为String然后再转为小写
}
}
Apply中调用方式为
process(new FilterAdapter(new LowPass()), s);
这样就可以调用Filter的导出类LowPass中分process了,而且没有改变Apply中的任何方法
这种叫做适配器模式,适配器中代码接受你所拥有的接口,并产生你所需要的接口。
注:仔细观察可以发现上面使用了接口之后,所有的方法都变成了public的,事实上只能用public用其他的会报错,因为接口中默认就是public的,继承和实现接口中覆盖方法都不能降低访问权限。