其中ArrayList就是结构中的对象结构,我们在列表中存放了实际类型不同的元素,然后访问的时候,不需要“visitor instanceof SomeClass”这种语句一样能完成遍历,因为在具体元素中,我们通过visit()方法,以参数this传递给访问者,访问者中是多个方法的重载,是静态分派的,恰好此时编译器是很清楚这个this的类型的,它的静态类型就是这个具体元素本身,然后在访问者(Visitor)的对应的方法中,我们再通过传过来的这个参数(某一个具体元素)来调用这个元素中的方法得到数据。
在回到前面的双重分派,我们知道,动态多分派的语言是很容易做到双重分派这一点的,可以通过接收者和参数(实际类型)来判断方法的调用,但是,Java是动态单分派的,只能通过接收者来动态分派,但是现在我们也清楚了,使用访问者模式,通过两次方法调用,我们依然实现了双重分派。
17、适配器模式(Adapter Pattern)
将一个类的接口转换成客户希望的另外一个接口。该模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
何时使用
一个程序想使用已经存在的类,但是该类所实现的接口和当前程序所使用的接口不一致时。
优点
目标与被适配者解耦 满足开-闭原则
原理就是保留现有的类所提供的服务,修改其接口,从而达到客户端的期望。
再者,适配器也分对象适配器和类适配器,先看下面代码再来解释。
举个例子,你有一个播放器,只能播放MP3式的音乐,但是现在需要它能播放flac式的,我们不能直接使用这个播放器,但可以添加一个适配器来解决这个问题:
原来的播放器(被适配者):
//被适配者class Adaptee{ void playMp3(Object src){ System.out.println("播放MP3:" src); }}
用户像使用的功能(目标):
//目标,也就是用户所希望使用的intece Target{ void playFlac(Object src);}
对象适配器:
//对象适配器public class ObjectAdapter implements Target{ private Adaptee adaptee; public ObjectAdapter(){ super(); adaptee = new Adaptee(); } @Override public void playFlac(Object src) { //可能需要对src作处理 adaptee.playMp3(src); }}
类适配器:
//类适配器public class ClassAdapter extends Adaptee implements Target { @Override public void playFlac(Object src) { //可能需要对src作处理 playMp3(src); }}
使用:
public class TestUse { public static void main(String args[]){ Adaptee adaptee = new Adaptee(); adaptee.playMp3("mp3"); Target target = new ClassAdapter(); target.playFlac("flac"); target = new ObjectAdapter(); target.playFlac("flac"); }}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-33893-34.html
而且舰龄老化