面向对象适配
假设已有一个软件系统,你希望它能和新的厂商类库搭配使用,但是这个新厂商所设计出来的接口,不同于旧厂商的接口:
你不想改变现有的代码,而且你也不能改变厂商的代码。可以写一个类,将新厂商的接口转换成你所期望的接口。
这个适配器工作起来就如同一个中间人,它将客户所发出的请求转换成厂商类能理解的请求。
如果它走起来像只鸭子,叫起来像只鸭子,它可能是一只包装了鸭子适配器的火鸡。
-
鸭子接口
public interface Duck { public void quack(); public void fly(); } 复制代码
-
绿头鸭是鸭子的子类
public class MallardDuck implements Duck { @Override public void quack() { System.out.println("嘎嘎叫"); } @Override public void fly() { System.out.println("飞起来了"); } } 复制代码
-
火鸡接口
public interface Turkey { void gobble(); void fly(); } 复制代码
-
野生火鸡
public class WildTurkey implements Turkey { @Override public void gobble() { System.out.println("咯咯叫"); } @Override public void fly() { System.out.println("只能飞一点距离"); } } 复制代码
现在,假设你缺鸭子对象,想用一些火鸡来冒充。显而易见,因为火鸡接口的不同,所以我们不能公然拿来用。
写个适配器吧:
/**
* 火鸡适配器
* 将火鸡适配成鸭子
* @author 陈添明
* @date 2019/1/13
*/
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
@Override
public void quack() {
turkey.gobble();
}
@Override
public void fly() {
for (int i = 0; i < 5; i++) {
turkey.fly();
}
}
}
复制代码
适配器模式解析
现在我们已经知道什么事适配器了,让我们后退一步,再次看看各部分之间的依赖。
客户使用适配器的过程如下:
- 客户通过目标调用适配器的方法对适配器发出请求。
- 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口。
- 客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。
定义适配器模式
将一个类的接口,转换成客户所期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。
适配器模式充满了良好的OO设计原则:使用对象组合,以修改的接口包装被适配者。这种做法还有额外的优点:被适配者的任何子类,都可以搭配适配器使用。
外观模式
假设你要建立一个家庭影院系统,内含DVD播放器、投影机、自动屏幕、环绕立体声,甚至还有爆米花机。
观赏电影(用困难方式)
想看电影,必须先执行一系列任务。
使用外观
- 现在为家庭影院系统创建一个外观类,它对外暴露了几个简单的方法,例如:watchMovie();
- 这个外观将家庭影院的诸多组件视为一个子系统,通过调用这个子系统,来实现watchMovie()方法。
- 外观只是提供更直接的操作,并未将原来的子系统隔离起来。如果你愿意使用子系统的高级功能,还是可以使用原来的子系统的。
- 外观不只是简化了接口,还将客户熊组件的子系统中解耦
- 外观和适配器都可以包装许多类,但是外观的意图是简化接口,而适配器的意图是将接口转换成不同的接口。
定义外观模式
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
最少知识原则
最少知识原则告诉我们要减少对象之间的交互,只留下几个“密友”。
最少知识原则:只和你的密友交谈
这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中的一部分,会影响到其他部分。
源码:github.com/chentianmin…
adapter包!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END