java基础——从设计模式讨论接口

接口

1. 完全解耦

只要一个方法操作的是类而非接口,那么就只能使用这个类及其子类。如果想使这个方法应用于不再此继承结构中的某个类,那么接口就可以在很大程度上放宽这种限制。例如:

public class Processor {
	public String name() {
		return getClass().getSimpleName();
	}

	Object process(Object input) {
		return input;
	}
}
public class Upcase extends Processor {
	String process(Object input) {
		return ((String) input).toUpperCase();
	}
}
public class Downcase extends Processor {
	String process(Object input) {
		return ((String) input).toLowerCase();
	}
}
public class Spiltter extends Processor{
	String process(Object input) {
		return Arrays.toString(((String)input).split(" "));
	}
}
public class Apply {
	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 ="He is still expected to be confirmed, due to the Republican majority in the Senate.";
	public static void main(String[] args) {
		process(new Upcase(),s);
		process(new Downcase(),s);
		process(new Spiltter(),s);
	}
}
Using ProcessorUpcase
HE IS STILL EXPECTED TO BE CONFIRMED, DUE TO THE REPUBLICAN MAJORITY IN THE SENATE.
Using ProcessorDowncase
he is still expected to be confirmed, due to the republican majority in the senate.
Using ProcessorSpiltter
[He, is, still, expected, to, be, confirmed,, due, to, the, Republican, majority, in, the, Senate.]

Apply.process()方法可以接受任何类型的Processor,并将其应用到一个Object对象上,然后打印结果。像本例这样创建一个能够根据所 传递参数对象 的不同而具有不同的方法被称为策略设计模式

现在我们假设有一组电子滤波器,它们看起来好像适用于Apply.process()方法。

public class Waveform {
	private static long counter;
	private final long id = counter++;

	public String toString() {
		return " WaveFrom " + id;
	}
}

public class Filter {
	public String name() {
		return getClass().getSimpleName();
	}

	public Waveform process(Waveform input) {
		return input;
	}
}

public class LowPass extends Filter {
	double cutoff;

	public LowPass(double cutoff) {
		this.cutoff = cutoff;
	}
	public Waveform process(Waveform input) {
		return input;
	}
}

public class HighPass extends Filter {
	double cutoff;

	public HighPass(double cutoff) {
		this.cutoff = cutoff;
	}
	public Waveform process(Waveform input) {
		return input;
	}
}

public class BandPass {
	double lowCutoff, highCutoff;

	public BandPass(double lowCut, double highCut) {
		lowCutoff = lowCut;
		highCutoff = highCut;
	}
	public Waveform process(Waveform input) {
		return input;
	}
}

Filter与Processor具有相同的元素接口,但是因为它并非继承自Processor,因此不能将Filter用于Apply.process()方法,主要是因为Apply.process()方法和Processor之间耦合过紧,已经超出了所需的程度。但是如果Processor是一个接口,那么这些限制就会变得松动,下面是对Processor和Apply的修改。

public interface Processor {
	String name();
	Object process(Object input);
}
public class Apply {
	public static void process(Processor p, Object s) {
		System.out.println("Using Processor"+p.name());
		System.out.println(p.process(s));
	}
}
public abstract class StringProcessor implements Processor {
	public String name() {
		return getClass().getSimpleName();
	}
	public abstract String process(Object input);
	public static String s = "He is still expected to be confirmed, due to the Republican majority in the Senate.";
	public static void main(String[] args) {
		Apply.process(new Upcase(), s);
		Apply.process(new Downcase(), s);
		Apply.process(new Splitter(), s);
	}
}
public class Upcase extends StringProcessor{
	public String process(Object input) {
		return ((String) input).toUpperCase();
	}
}
public class Downcase extends StringProcessor {
	public String process(Object input) {
		return ((String) input).toLowerCase();
	}
}
public class Splitter extends StringProcessor{
	public String process(Object input) {
		return Arrays.toString(((String)input).split(" "));
	}
}
Using ProcessorUpcase
HE IS STILL EXPECTED TO BE CONFIRMED, DUE TO THE REPUBLICAN MAJORITY IN THE SENATE.
Using ProcessorDowncase
he is still expected to be confirmed, due to the republican majority in the senate.
Using ProcessorSplitter
[He, is, still, expected, to, be, confirmed,, due, to, the, Republican, majority, in, the, Senate.]

但是,经常碰到的情况是无法修改想要使用的类。例如,在电子滤波器的例子中,类库是被发现而非创建的。在这种情况下,可以使用 适配器设计模式 。适配器中的代码将接受你所拥有的接口,并产生你所需要的接口,就像下面这样:

public class FilterAdapter implements Processor {
	Filter filter;
	public FilterAdapter(Filter filter) {
		this.filter = filter;
	}
	@Override
	public String name() {
		return filter.name();
	}
	@Override
	public Object process(Object input) {
		return filter.process((Waveform) input);
	}
}
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 ProcessorLowPass
 WaveFrom 0
Using ProcessorHighPass
 WaveFrom 0
Using ProcessorBandPass
 WaveFrom 0

FilterAdapter的构造器接受所拥有的Filter,然后生成所需要的Processor接口的对象。FiltterAdapter还使用到了代理的思想。

2. Java多重继承

Java的依靠接口实现多重继承,一个类可以 implements 多个接口,(注意:继承类和继承接口同时存在的时候,extends在implements之前),同时根据前几章的向上转型特性,当一个类继承了多个接口的时候,也可以向上转型为多种类型。

3. 通过继承扩展接口

接口之间也存在继承关系,通过继承接口可以实现功能的扩展。

3.1 组合接口时的名字冲突

在打算组合的不同的不同接口中使用相同的方法名通常会造成代码可读性的混乱,应该避免出现这种情况。

4. 适配接口

接口最吸引人之处就是允许同一个接口具有多个不同的具体实现,再简单的情况下它的体现形式通常是一个接受接口类型的方法,而该接口的实现和向该接口传递的对象则取决于方法的使用者。因此接口最常用的就是策略设计模式。

最典型的例子就是Scanner类的构造器,它接受一个Readable接口。通过这种方式,Scanner可以作用于更多的类型。

扫描二维码关注公众号,回复: 4726660 查看本文章
Scanner(Readable source);

5.接口中的域

放入接口中的任何域都自动是static和final的访问权限是public,因此接口就成了一种成了一种很便捷的用来创建常量组的工具。

5.1 初始化接口中的域

在接口中定义的域不能是“空final”,但是可以被非常量初始化(表达式)。当然这些域不是接口中的一部分,它的值被存在该接口的静态存储区域内。

6.嵌套接口

接口可以嵌套在接口或其它类中。就像非嵌套接口一样可以定义public , private 和 报访问权限。private的接口只能在定义它的类之内被实现(否则没有意义)。嵌套在另一个类的接口 自动就是public的,当某类实现了该接口时不需要实现嵌套在内部的接口。

7. 接口与工厂

生成遵循某个接口的对象的典型方法就是 工厂模式 ,这与直接调用构造函数不同,我们在工厂对象调用的是创建方法,而工厂对象将生成接口的某个实现对的对象。

public interface Service {
	void methods1();
	void methods2();
}
public interface ServiceFactory {
	Service getService();
}
public class Implementation1 implements Service {
	Implementation1() {
	}
	@Override
	public void methods1() {
		System.out.println("Implementationa1 methods1");
	}
	@Override
	public void methods2() {
	System.out.println("Implementationa1 methods2");
	}
}
public class Implementation2 implements Service {
	Implementation2() {
	}
	@Override
	public void methods1() {
		System.out.println("Implementationa2 methods1");
	}
	@Override
	public void methods2() {
	System.out.println("Implementationa2 methods2");
	}
}
public class Implementtation1Factory implements ServiceFactory {
	@Override
	public Service getService() {
		return new Implementation1();
	}
}
public class Implementtation2Factory implements ServiceFactory {
	@Override
	public Service getService() {
		return new Implementation2();
	}
}
public class Factories {
	public static void serviceConsumer(ServiceFactory factory) {
		Service s = factory.getService();
		s.methods1();
		s.methods2();
	}
	public static void main(String[] args) {
		serviceConsumer(new Implementtation1Factory());
		serviceConsumer(new Implementtation2Factory());
	}
}

猜你喜欢

转载自blog.csdn.net/qq_37339399/article/details/85040370