接口实现松耦合
来源:互联网 发布:淘宝几十元澳洲羊毛被 编辑:程序博客网 时间:2024/05/03 19:59
来自java编程思想9.3 完全解耦
只要一个方法操作是类而非接口,那么你就只能使用这个类及其子类。如果你想要将这个方法应用到不在此继承结构中的某个类,那么你就达不到目的。接口可以很大程度放宽这种限制,因此使用接口而非继承使得我们可以编写可复用性更好的代码。PS:书中前面也说道了,慎用继承,尽量使用组合!
例如:假设有一个Processor类,产生一个name()方法;另外还有一个process()方法,该方法接受输入参数,修改它的值产生输入。这个类作为基类被扩展,用来创建不同的Processor。
package interfaces.classprocessor;import static net.mindview.util.Print.*;import java.util.Arrays;class Processor{public String name(){return getClass().getSimpleName();}Object process(Object input){return input;}}class Upcase extends Processor{String process(Object input){return ((String)input).toLowerCase();}}class Downcase extends Processor{String process(Object input){return ((String)input).toUpperCase();}}class Splitter extends Processor{String process (Object input){return Arrays.toString(((String)input).split(" "));}}public class Apply {public static void process(Processor p,Object s){print("Using processor "+p.name());print(p.process(s));}public static String s = "Disagreement with beliefs is by definition incorrct";public static void main(String[] args) {process(new Upcase(), s);process(new Downcase(), s);process(new Splitter(), s);}}
输出:
Using processor Upcase
disagreement with beliefs is by definition incorrct
Using processor Downcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRCT
Using processor Splitter
[Disagreement, with, beliefs, is, by, definition, incorrct]
Apply.process()方法可以接受任何类型的Processor,并将其应用到一个Object对象上,然后打印结果。像本例刚开始看我们觉得设计是不错的,创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,称为策略模式。这类方法包含执行算法中固定不变的部分,而“策略”包含变化的部分,策略就是传进去的参数。
现在有一个电子滤波器好像也是用Apply.process()方法。
在interfaces.filters包中创建相关的代码
package interfaces.filters;public class Waveform {private static long counter;private static long id = counter++;public String toString(){return "Waveform" + id;}}
基类Filter代码实现
package interfaces.filters;public class Filter {public String name(){return getClass().getSimpleName();}public Waveform process(Waveform input){return input;}}
下面继承Filter类产生的继承类
package interfaces.filters;public class LowPass extends Filter {double cutoff;public LowPass(double cutoff){this.cutoff = cutoff;}public Waveform process(Waveform input){return input;}}
package interfaces.filters;public class HighPass extends Filter {double cutoff;public HighPass(double cutoff){this.cutoff = cutoff;}public Waveform process(Waveform input){return input;}}
package interfaces.filters;public class BandPass extends Filter {double lowCutoff,highCutoff;public BandPass(double lowCutoff,double highCutoff){this.lowCutoff = lowCutoff;this.highCutoff = highCutoff;}public Waveform process(Waveform input){return input;}}
通过上面代码我们可以发现Filter和Processor具有相同接口元素,但是因为它不是继承Processor,因此你不能将Apply.process()方法应用到Filter上。
我们反过来找原因就会发现,主要是因为Apply.process()方法和Processor之间耦合过紧,已经超出了所需要的程度了,使得应该复用Apply.process()时复用却 用不了。
如果我们把Processor 定义为一个接口,那么耦合就会降低,就能复用Apply.process(),下面是修改的版本。
package interfaces.interfaceprocessor;public interface Processor {String name();Object process(Object input);}
package interfaces.interfaceprocessor;import static net.mindview.util.Print.*;public class Apply {public static void process(Processor p,Object s){print("Using Processor "+p.name());print(p.process(s));}}
package interfaces.interfaceprocessor;import java.util.Arrays;public abstract class StringProcessor implements Processor{public static void main(String[] args) {Apply.process(new Upcase(), string);Apply.process(new Downcase(), string);Apply.process(new Splitter(), string);}public String name() {return getClass().getSimpleName();}public abstract String process(Object input) ;public static String string = "disagreement with beliefs is by definition incorrct";}class Upcase extends StringProcessor{public String process(Object input) {return ((String)input).toUpperCase();}}class Downcase extends StringProcessor{public String process(Object input) {return ((String)input).toLowerCase();} }class Splitter extends StringProcessor{@Overridepublic String process(Object input) {return Arrays.toString(((String)input).split(" "));}}结果输入:
Using Processor Upcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRCT
Using Processor Downcase
disagreement with beliefs is by definition incorrct
Using Processor Splitter
[disagreement, with, beliefs, is, by, definition, incorrct]
这个时候我们还是无法Apply.process()方法在Filter上,但是我们可以引入“适配器”设计模式。适配器中代码将接受你所拥有的接口,并产生你所需要的接口,就像下面一样:
package interfaces.interfaceprocessor;import interfaces.filters.Filter;import interfaces.filters.Waveform;public class FilterAdapter implements Processor {@Overridepublic String name() {return filter.name();}@Overridepublic Waveform process(Object input) {return filter.process((Waveform)input);}Filter filter ;public FilterAdapter(Filter filter){this.filter = filter;}}
package interfaces.interfaceprocessor;import interfaces.filters.BandPass;import interfaces.filters.HighPass;import interfaces.filters.LowPass;import interfaces.filters.Waveform;public class FilterProcessor {public static void main(String[] args) {Waveform w = new Waveform();Apply.process(new FilterAdapter(new LowPass(1.0)), w);Apply.process(new FilterAdapter(new HighPass(2.0)), w);Apply.process(new FilterAdapter(new BandPass(3.0, 4.0)), w);}}
运行结果:
Using Processor LowPass
Waveform 0
Using Processor HighPass
Waveform 0
Using Processor BandPass
Waveform 0
总结:接口常用方法就是前面说到的策略设计模式,你编写一个执行某些操作的方法,而该方法接受一个同样是你指定的接口。你主要是声明:“你可以用任何你想要的对象来调用我的方法,只要你的对象遵循我的接口。”这使得方法更加灵活、通用,并且更具有复用性。
前期设计我们不应该考虑适配器设计模式,而应该通过重构来统一接口,但是往往系统升级改造使得我们需要使用适配器模式为无赖之举。
- 接口实现松耦合
- 消息耦合还是接口耦合
- 消息耦合还是接口耦合
- 消息耦合还是接口耦合
- 消息耦合还是接口耦合
- 消息耦合还是接口耦合
- Spring松耦合的实现
- 耦合、紧耦合、松耦合
- interface接口解耦合
- 接口与耦合
- 松耦合和紧耦合
- C++进阶 降低文件间的编译依存关系(接口与实现解耦合)
- 基于 OSGi 服务模型实现组件之间松耦合通信
- .net实现松耦合事件的三种方法
- 实体类如何与算法实现松耦合
- 桥接模式(把接口和实现分为两个继承树,而不是将实现来继承接口,造成实现和接口耦合
- 强内聚与松耦合
- 强内聚、松耦合
- 精通C#学习笔记之事件(一)使用委托的弊端
- JBPM4 学习使用总结
- python map()函数
- 从STL中的list删除元素
- 23种设计模式汇总整理
- 接口实现松耦合
- 为什么没有blog android客户端
- 【USACO】Wormholes(暴力搜索)
- codeforces 526 E(神题)
- C语言中scanf()和gets()的比较
- elasticsearch源码分析---TransportClient
- Android如何显示音标
- string类的构造函数,析构函数,拷贝构造函数和赋值构造函数
- 【C语言】斐波那契数