概述
适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类一起工作。
在软件开发中,适配器模式用来解决的这样的问题:系统的数据和行为都正确,但接口不符合我们的需求,此时,我们可能需要使用适配器模式,目的是使控制范围之外的一个原有对象与某个接口匹配。
在GOF的设计模式中,适配器模式分为类适配器模式、对象适配器模式、接口适配器模式,我们具体学习下这三种适配器模式。
一、适配器模式
1.1 、类的适配器模式
类的适配器模式的核心思想是:有一个Source类,拥有一个方法,待适配。目标接口是Target,通过Adapter类,将Source的功能扩展到Target中。其UML图如下:
类的适配器模式由以下部分组成:
目标角色(Target):这个目标不可以是类,必须是接口
源角色(Source):需要适配的类。
适配器角色(Adapter):适配器把源接口转换为目标接口,这个角色不可以是接口,必须是具体类,该类继承Source,实现Target接口。
代码部分:
class Source{
public void operation1(){
System.out.println("我是等待适配的方法");
}
}
interface Target{
public void operation1();
public void operation2();
}
class Adapter extends Source implements Target{
@Override
public void operation2() {
System.out.println("仅仅实现接口的一个方法");
}
}
public class Test1 {
public static void main(String[] args) {
Adapter adapter = new Adapter();
adapter.operation1();
adapter.operation2();
}
}
运行结果:
1.2、对象的适配器模式
对象的适配器模式和类的适配器模式相同,只是将Adapter类做修改,不继承Source,而是持有Source的实例。其UML图如下:
代码部分,只需要修改Adapter:
class Adapter implements Target{
private Source source;
public Adapter(Source source) {
this.source = source;
}
@Override
public void operation1() {
source.operation1();
}
@Override
public void operation2() {
System.out.println("仅仅实现接口的一个方法");
}
}
//客户端调用:
public class Test2 {
public static void main(String[] args) {
Source source = new Source();
Adapter adapter = new Adapter(source);
adapter.operation1();
adapter.operation2();
}
}
运行结果:
1.3 接口的适配器模式
当我们写一个有多个方法的接口的实现类时,不得不实现其所有的方法。但其实并不是所有的方法都是我们需要的。而接口的适配器模式,可以借助一个抽象类,实现该接口,我们只要实现这个抽象类就好了,其UML图如下:
代码部分:
interface Sourceable {
public void operation1();
public void operation2();
}
abstract class Source implements Sourceable {
public void operation1() {}
public void operation2() {}
}
class AdapterA extends Source {
public void operation1() {
System.out.println("我只想实现operation1方法");
}
}
class AdapterB extends Source {
public void operation2() {
System.out.println("我只想实现operation2方法");
}
}
class AdapterC extends Source {
public void operation1() {
System.out.println("我乐意实现operation1方法");
}
public void operation2() {
System.out.println("我也可以实现operation2方法");
}
}
public class Test3 {
public static void main(String[] args) {
AdapterA a1 = new AdapterA();
AdapterB a2 = new AdapterB();
AdapterC a3 = new AdapterC();
a1.operation1();
a1.operation2();
a2.operation1();
a2.operation2();
a3.operation1();
a3.operation2();
}
}
运行结果:
二、案列分析
《西游记》中第五十九回《唐三藏路阻火焰山 孙行者一调芭蕉扇》中,师徒四人来到火焰上,要借铁扇公主的扇子扇灭火焰山的熊熊大火,孙悟空是没有这个功能的,借了三回也没借来。最后还是观音菩萨解的难。
假若我们想让孙悟空既能七十二变化,又能扇灭熊熊大火,岂不是大圣就把这事儿办了么?在适配器模式中,就很容易做到。其UML图如下:
代码部分:
class TieShan{
public void windly(){
System.out.println("只有我铁扇公主才能扇灭火");
}
}
interface Target{
public void windly();
public void change();
}
class Monkey extends TieShan implements Target{
@Override
public void change() {
System.out.println("老孙会七十二变");
}
}
public class Test4 {
public static void main(String[] args) {
Monkey monkey = new Monkey();
monkey.change();
monkey.windly();
}
}
运行结果:
从结果看,明明调用的是孙悟空,但也能扇灭火焰山的熊熊大火了。
所有示例代码地址:Adapter
三、模式结语
三种适配器的适用场景:
当一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新的类,继承原有的类,实现新的接口即可。
当一个类转换成满足另一个新接口的对象时,可以使用对象的适配器模式,创建一个Adapter类,持有原类的一个实例 ,调用该实例的方法。
当不希望实现一个接口中的所有方法时,可以创建一个抽象类,实现所有方法,在用新的类来继承抽象类即可。
欢迎大家留言评论,点击查看其它设计模式。
最后
以上就是现代大叔为你收集整理的设计模式之适配器模式的全部内容,希望文章能够帮你解决设计模式之适配器模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复