疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java接口实现松耦合


 

   

  只要一个方法操作是类而非接口,那么你就只能使用这个类及其子类。如果你想要将这个方法应用到不在此继承结构中的某个类,那么你就达不到目的。接口可以很大程度放宽这种限制,因此使用接口而非继承使得我们可以编写可复用性更好的代码。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{

  @Override

  public 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 {

  @Override

  public String name() {

  return filter.name();

  }

  @Override

  public 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