`
airu
  • 浏览: 267454 次
  • 性别: Icon_minigender_1
  • 来自: 云南
社区版块
存档分类
最新评论

每天一个(设计模式)-- Adapter 模式(适配器模式)

 
阅读更多
适配器模式是最常用的设计模式之一。我们随处可以见到他的身影。例如Android中的某些监听器接口,还有著名的ListAdapter。

适配器模式,实际上是一个接口转换模式。也就是我们要把一个接口转换为另外一个接口。也许你要问,为什么要这么做呢? 当然,我们也可以不必这么做,直接实现所需要的接口,不就成了吗? 对于一些教学上的例子来看,确实是这样,但是,如果要转换的接口很复杂,而且,我们很可能只是需要另外一个接口的某些实现,就可以完成新接口的大部分功能,这样的 话,使用了Adapter模式,对于客户端来说,即使Adapter内的实现发生了变化,也并不影响他的继续使用。

简而言之,使用适配器的场景就是: 新接口使用老的实现来过度。做法有两种,
第一: 实现新接口(不是真正的实现,只是看起来像),集成老的实现类。
第二: 实现新接口(该有的方法必须有,内容可空),包含老接口。
这两种类图分别如下:







这两种方法都可以实现Adapter,我更喜欢第二种。优先组合。继承不仅占用了唯一继承权,而且还继承了很多不必要的东西。

下面我们以代码来看看。这个代码使用插座的故事来说明适配器。

首先,很久以前我们的插座是2口的,标准如此。
public interface PowerSocket {
	public static final int FL = 0;
	public static final int ZL = 1;
	public int getFrontLine();
	public int getZeroLine();
}

为了说明问题,方法只是实例而已。我们的插座有两根线,火线零线

然后我们根据这个标准生产了一种插座。GN插座。
public class GNPowerSocket implements PowerSocket{

	@Override
	public int getFrontLine() {
		// TODO Auto-generated method stub
		return PowerSocket.FL;
	}

	@Override
	public int getZeroLine() {
		// TODO Auto-generated method stub
		return PowerSocket.ZL;
	}

}

很好。一切都很顺利。突然,着火了。。。。为了更安全,我们决定加入一个接地的线吧。
于是新的标准出来了。地线是必须的。
public interface NewPowerSocket {
	public static final int GL = 3;
	public int getFrontLine();
	public int getZeroLine();
	public int getGroundLine();
}


然后又有了三个口的插座。很多电器都变成三口了。可是,我觉得再去买三口插座,太贵了。或者某一天我突然到了个陌生的环境中,发现只有两口的插座怎么办?
为了解决这个问题。我只好买了个转换器。两口转三口。
public class SocketAdapter implements NewPowerSocket{
	
	private PowerSocket GNps;
	public SocketAdapter(PowerSocket ps){
		this.GNps = ps;
	}
	@Override
	public int getGroundLine() {
		// TODO Auto-generated method stub
		return NewPowerSocket.GL;
	}

	@Override
	public int getFrontLine() {
		// TODO Auto-generated method stub
		return GNps.getFrontLine();
	}

	@Override
	public int getZeroLine() {
		// TODO Auto-generated method stub
		return GNps.getZeroLine();
	}

}

这里有个小问题,其实这个例子不太合适。稍后再说。

好了,我们看看使用过程。
public class Client {
	public void useSocket(NewPowerSocket nps){
		nps.getFrontLine();
		//dosomething...
		//...
	}
	public static void main(String[] args){
		Client client = new Client();
		PowerSocket ps = new  GNPowerSocket();
		SocketAdapter adapter = new SocketAdapter(ps);
		client.useSocket(adapter);
	}
}


好了,来说说这个例子的问题,其实这个例子中的两个接口,都很小,实现起来超级方便。完全可以直接实现吧。好比这个插座,大家都买三口的吧,花不了几个钱。。。
而且,我们这里的适配器,完全就是一个三口插座。哈哈。
还有,这里使用的委托的方式实现的。

实际情况中,适配器并不一定完全实现接口方法(必须写出方法,内容可以为空),而且复杂的可重用的实现使用老的接口类。所以上面的代码,仅仅是一个了解。
  • 大小: 46.2 KB
  • 大小: 51.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics