设计模式之:适配器模式详解(Java实现)

我们从它的名字中就可以清楚它的含义,这个模式呢,它直到一个适配器的作用。 那么什么是适配器呢?(请自行百度)

哈,开个玩笑,为了让大家认识一个适配器,来举个例子吧。众所周知,苹果在iPhone 7之后的手机产品(包括iPhone 7)就已经取消了3.5mm的耳机接口,而取代它的就是Lightning接口。那我们如果只有一个3.5mm的耳机,怎么去用新的iPhone手机听歌呢? 这时候,就需要适配器的帮忙。在这个例子里,我们也可以称它为转接头。
iPhone的适配器
就是上面图片里的这个小家伙啦,它就是所谓的适配器,将一个接口,转换成用户期待的另一个接口。在这个实例中,我们将Lightning接口转换成我们期待的(也是将用到的)3.5mm的耳机接口。

上面已经清地讲解了适配器模式的原理,当我们想更深入地去了解它时,我们就要了解一个词:扩展。在我个人的理解中,这个扩展是适配器模式的核心思想,不急,我们来一步步,慢慢深入地了解适配器。

适配器分为三种,按理解的难易程度,分别为:接口适配器,类适配器,对象适配器。

在我们了解接口适配器之前,我们要先知道它是干嘛用的。简单地来说,就是当我们要实现某一个接口中的部分方法时,就得用这个接口适配器去实现它。这是为什么呢?我们直接实现类去实现这个接口不行吗? 这就涉及到我们对接口的基本概念有没有熟悉。当我们要定义一个类用implements关键字实现一个接口时,我们必须实现接口中的所有方法。但如果这个类为抽象类,我们可以只实现接口中的部分方法就行了。所以说,当这个接口中有我们不想使用到的方法,此时,我们就需要借助“接口适配器”来实现它了。

再来,我们看看接口适配器的UML图,让我们更好地去了解它的结构。
设计模式之:适配器模式详解(Java实现)_第1张图片
从图中可得知,我们有三个对象:
Human:我们定义的一个接口,其中有三个抽象方法。
Adapter:一个抽象类,在这个结构扮演者适配器的角色。
Child:一个实现类,它继承了Adapter,并实现了其中的eat()方法 和 sleep()方法。
下面我们来看看代码
Hunam接口:

public interface Human {
	void eat();

	void work();

	void sleep();
}

Adapter适配器

public abstract class Adapter implements Human {
	public void eat() {
	}

	public void work() {
	}

	public void sleep() {
	}
}

Child实现类

public class Child extends Adapter {

	@Override
	public void eat() {
		System.out.println("生下来就会吃喝");
	}

	@Override
	public void sleep() {
		System.out.println("生下来就会睡觉");
	}

}

Text测试类

public class Text {
	public static void main(String args[]) {
		Human hz = new Child();
		hz.eat();
		hz.sleep();
	}
}

最后运行结果:

生下来就会吃喝
生下来就会睡觉

接下来讲讲类的适配器
当我们的目标接口是A接口(不可以访问其它接口),可是A接口中并没有我们想要的方法,而B类中却有我们想要使用的方法时,我们就可以用适配器,将B类中的方法扩展到A接口中。
首先,我们还是先看看它的UML图:
设计模式之:适配器模式详解(Java实现)_第2张图片
它呢,同相拥有三个对象
A接口:我们的目标接口
B类:拥有我们想要的方法,是我们的目标类
Adapter类:作为适配器继承目标类B的同时,实现了接口A。

接口A

public interface A {
	void eat();

	void sleep();

	void work();
}

目标类B

public class B{

	public void work() {
		System.out.println("学会了工作");
	}

}

适配器Adapter

public class Adapter extends B  implements A {
	public void eat() {
	}

	public void sleep() {
	}
}

测试类

public class text {
	public static void main(String args[]) {
		A a = new Adapter();
		a.work();
	}
}

最后运行结果:

学会了工作

最后我们讲讲对象适配器,在看对象适配器前,最好把类的适配器先理解了,再学习对象适配器就容易多了。
在类的适配器中呢,我们通过继承来实现方法的扩展而在对象适配器中,我们不通过继承了,而是通过持有目标类的实例来解决兼容性的问题。

所以我们只需要更改Adapter类的代码即可。

public class Adapter implements A {
	private B b;

	public Adapter(B b) {
		this.b = b;
	}

	public void eat() {
	}

	public void work() {
		b.work();
	}

	public void sleep() {
	}
}

在这个代码块中,我们定义了一个私有的 B类参数b,然后通过Adapter的构造方法将其实例导入。这样子我们就在Adapter类中拥有了B的实例,可以运用这个实例对B中的方法进行调用。

public class text {
	public static void main(String args[]) {
		B b = new B();           //创建一个B的实例
		A a = new Adapter(b);    //通过Adapter的构造方法将其导入适配器中。
		a.eat();
		a.work();
		a.sleep();
	}
}

最后运行结果(与类适配器的运行结果相同):

学会了工作

到了这里,我们已经将适配器模式学会了。接下来,我们来总结一下学习的内容。
接口适配器:当我们想到实现接口中的部分方法时,我们可以创建一个适配器,然后通过继承这个适配器实现我们想要的方法。
类适配器:当我们 要实现的方法 的类 不是我们所期望的接口时,我们可以通过类适配器继承这个目标类并实现接口,就可以解决兼容问题。
对象适配器:当我们希望将一个对象转换成满足目标接口的新对象时,可以用适配器持有这个对象的实例,在适配器是调用实例中的方法即可。


可能这篇博文比较啰嗦,但为了可以更清晰地描述适配器模式还是不得不如此。最后希望大家能够学有所获,因水平有限,若有不尽之处望大家指出。

你可能感兴趣的:(java)