大家好,又见面了,我是全栈君。
轻轻的我走了,
正如我轻轻的来;
我轻轻的招手,
作别西天的云彩。
——徐志摩 《再别康桥》
故事背景
把奶茶店盘了出去,我和设计模式MM,继续上路,坐着冒着烟的飞机来到了剑桥,这里真是个美丽的地方,我用手机拍了很多的照片手机没电了,也玩的累了。
找了个酒店 ,准备休息一下,然后给我的手机充充电。 才知道英国的插座都是下面这个样子:
而我的手机充电器是这个样子的:
那这就比较尴尬了,我并不能改变电源的插座,也不能改变我手机的充电器,因此我需要一个转换器,或者说是一个适配器。适配器大概是这个样子,大概是这样的,画的不好,哈哈:
设计模式MM看到此种场景,就告诉我,这种情况和 一种叫做 适配器模式的武功很相似。让我去学习学习!
背景纯属yy!为了引出本篇的主题。
故事主角
在上面的背景描述中,我们知道不能改变电源的插座,也不能改变手机的充电器,也就是手机的充电器不认识这个插座的(不能兼容这个插座)。类比在代码的世界中,就是有一个完整的系统A,我们需要使用系统A中某个类的功能(方法),但是我们的客户端不认识这个系统A中这个类,只认识另外要给不相关的接口。
注:系统A中的这个类和客户端代码都是一套完整的结构,不能修改!(这个和插座和手机充电器一样,都是完整的,不能修改!)
适配器模式(Adapter Pattern):将类的一个接口,转换成为客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。
适配器模式从实现方式上分为两种,对象适配器(组合)和类适配器(继承)。在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承(或实现)关系。
下面实际开发中,对象适配器使用频率更高,对象适配器模式结构图:
- Target(目标抽象类):定义客户所需接口。可是一个抽象类或者接口。
- Adapter(适配器类):是配送可以调用另一个接口,作为转换器,是适配器中的核心。
- Adaptee(适配者类):适配者也就是被适配器的对象。
简单代码表示:
class Adapter implements Target{
private Adaptee adaptee;//适配者对象的引用
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
public void request(){
adaptee.specificRequest();//调用适配器方法
}
}
武功修炼
通过对上面的适配器的简单学习后,我们实现手机充电的难题。
第一种适配器不需要做什么工作,只需要适配两个类即可。就像一根粗的水管和一根细的水管要接在一起,那么需要一个适配的转接水管,这个转接的水管内部不进行任何处理,只是一个适配作用。
//酒店插座
public class HotelSocket {
public void socket(){
System.out.println("四个头插座充电");
}
}
//抽象的目标接口类
public interface Socket {
void socket();
}
public class SockterAdapter implements Socket{
private HotelSocket socket;
public SockterAdapter(HotelSocket socket){
this.socket = socket;
}
@Override
public void socket() {
System.out.println("适配器转换.......");
socket.socket();
}
}
public class Phone {
private Socket adapter;
public Phone(Socket adapter){
this.adapter = adapter;
}
//手机充电
public void charger(){
System.out.println("手机充电....");
adapter.socket();
}
}
public class Test {
public static void main(String[] args) {
HotelSocket hotelSocket = new HotelSocket();
Socket socket = new SockterAdapter(hotelSocket);
Phone phone = new Phone(socket);
phone.charger();
}
}
第二种适配器因为四头的插座电压为250V,而手机需要的充电电压是5V,所以适配器需要将电压进行转换。
//酒店插座
public class HotelSocket {
public int socket(){
return 250;
}
}
//抽象的目标接口类
public interface Socket {
int socket();
}
public class SockterAdapter implements Socket{
private HotelSocket socket;
public SockterAdapter(HotelSocket socket){
this.socket = socket;
}
@Override
public int socket() {
int soucre = socket.socket();
//适配器进行处理,内部做了一些工作
return soucre / 50;
}
}
public class Phone {
private Socket adapter;
public Phone(Socket adapter){
this.adapter = adapter;
}
//手机充电
public void charger(){
int v = adapter.socket();
if(v == 5){
//只有是5v的才能充电
System.out.println("电压符合标准,充电中.....");
}else{
System.out.println("不能充电");
}
}
}
public class Test {
public static void main(String[] args) {
HotelSocket hotelSocket = new HotelSocket();
Socket socket = new SockterAdapter(hotelSocket);
Phone phone = new Phone(socket);
phone.charger();
}
}
总结
优点:
– 引入一个适配器类,重用现有的适配者,无须修改原有结构。(如手机充电器例子,引入适配器则不需要修改插座和手机充电器)。
– 增加了类的透明性和复用性。(如手机充电器例子,手机不用知道插座输入的电压到底是多少,插座输入的电压对于手机充电器是透明的,并且这个适配器不仅能适配我的手机,以后其他的和我手机一样的充电器也可以用,则就具有复用性。)
– 灵活性比较好。(如果我从英国去了日本,我也只需要更换适配器即可,不需要对我的手机充电器做修改,也不需要对日本的插座做修改)
缺点:
– 在java中类适配器只能适配一个类,因为java不支持多重继承。
– 对象适配器要更换被适配者比较麻烦,需要适配器中的所有适配的方法进行修改。
适用场景:
-
如果两个接口不兼容情况,并且这两个接口都不能进行修改,结构已经固定了。要使整个两者之间可以合作。
-
系统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统的需要,甚至没有这些类的源代码。
-
想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
注:适配器模式是补救措施,所以在系统设计过程中请忘掉这个设计模式,这个模式只是在你无可奈何时的补救方式。
Next 期待下一篇吧!讲讲外观模式!
参考
- 史上最全设计模式导学
- 《Head First 设计模式》
- 《图解设计模式》
本专栏文章列表
一、设计模式-开篇—为什么我要去旅行? #和设计模式一起旅行#
二、设计模式-必要的基础知识—旅行前的准备 #和设计模式一起旅行#
三、设计模式介绍—她是谁,我们要去哪里? #和设计模式一起旅行#
四、单例模式—不要冒充我,我只有一个! #和设计模式一起旅行#
五、工厂模式—旅行的钱怎么来 #和设计模式一起旅行#
六、策略模式—旅行的交通工具 #和设计模式一起旅行#
七、观察者模式——关注我,分享旅途最浪漫的瞬间! #和设计模式一起旅行#
八、装饰者模式—巴厘岛,奶茶店的困扰! #和设计模式一起旅行#
九、命令模式—使用命令控制奶茶店中酷炫的灯 #和设计模式一起旅行#
十、模板方法模式—制作更多好喝的饮品! #和设计模式一起旅行#
十一、代理模式 —专注,做最好的自己!#和设计模式一起旅行#
十二、适配器模式——解决充电的烦恼 #和设计模式一起旅行#
十三、外观模式—— 简化接口 #和设计模式一起旅行#
十四、迭代器模式—— 一个一个的遍历 #和设计模式一起旅行#
十五、组合模式—— 容器与内容的一致性 #和设计模式一起旅行#
十六、状态模式—用类表示状态 #和设计模式一起旅行#
十七、访问者模式-访问数据结构并处理数据 #和设计模式一起旅行#
十八、职责链模式-推卸责任,不关我的事,我不管!#和设计模式一起旅行#
十九、原型模式—通过复制生产实例 #和设计模式一起旅行#
二十、设计模式总结—后会有期 #和设计模式一起旅行#
如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到,谢谢!
如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!
欢迎访问我的csdn博客,我们一同成长!
不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!
博客首页 : http://blog.csdn.net/u010648555
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/121091.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...