结构型设计模式之适配器模式
适配器模式
适配器模式(Adapter Pattern)又叫做变压器模式,属于结构型设计模式。
它的功能是将一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作。
适配器就像一个中间层,起着转化委托的作用,将一种接口转化为另一种符合需求的接口。
分类
适配器模式有3种形式:类适配器、对象适配器、接口适配器
类适配器:
类适配器的原理就是通过继承来实现适配器功能。
对象适配器:
对象适配器的原理就是通过组合来实现适配器功能。
接口适配器:
接口适配器的主要原理就是原理利用抽象类实现接口,并且空实现接口众多方法。
应用场景
1.已经存在的类,它的方法和需求不匹配(方法结果相同或相以)的情况。
2.适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似以而接口不相同情况下的解决方案。
说明:
当系统存在两种接口A和B,客户端只支持访问A接口,但是当前系统没有A接口对象,但是有B接口对象,但客户无法识别B接口,因此需要通过一个适配器C,将B接口内容转换成A接口,从而使得客户能够从A接口获取得到B接口内容。
举例:在不同的国家电源电压不一致,但是笔记本充电器通常有一个电压范围,其相当于使用了适配器,让其适应了不通过国家的电压。
优缺点
优点:
1.能提高类的透明性和复用,现有的类复用但不需要改变。
2.目标类和适配器类解耦,提高程序的扩展性。
3.在很多业务场景中符合开闭原则。
缺点:
1.适配器编写过程需要全面考虑,可能会增加系统的复杂性。
2.增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。
主要角色
1.目标角色(Target)
目标角色也就是期望的接口
2.源角色(Adaptee)
存在于系统中,内容满足客户需求(需转换),但接口不匹配的接口实例
3.适配器(Adapter)
将源角色(Adaptee)转化为目标角色(Target)的类实例
适配器模式各角色之间的关系
需要的是Target接口,但Target接口设有一个实例符合需求,而Adaptee实例符合需求;但是无法直接使用Adaptee(接口不兼容);因此需要一个适配器(Adapter)来进行中转,让Adaptee能转化为Target接口形式;
类适配器
类适配器的原理就是通过继承来实现适配器功能。
让Adapter实现Target接口,并且继承Adaptee,这样Adapter就具备Target和Adaptee的特性,就可以将两者进行转化。
举例:以不同设备使用不同交流电为例,通过电源适配器进行转换说明。
创建目标角色(Target)
public interface Target {
int out();
}
创建源角色(Adaptee)
public class Adaptee{
public int input() {
System.out.println("输入交流电: 220V");
return 220;
}
}
创建适配器(Adapter)
public class Adapter extends Adaptee implements Target {
@Override
public int out() {
int input220V = super.input();
int output = input220V / 2;
System.out.println("输出交流电: " + output + "V");
return output;
}
}
客户端调用
public static void main(String[] args) {
Target adapter = new Adapter();
int result = adapter.out();
System.out.println(result);
}
输入交流电: 220V
输出交流电: 110V
110
对象适配器
对象适配器的原理就是通过组合来实现适配器功能。
让Adapter实现Target接口,然后内部持有Adaptee实例,然后再Target接口规定的方法内转换Adaptee。
创建目标角色(Target)
public interface Target {
int out();
}
创建源角色(Adaptee)
public class Adaptee{
public int input() {
System.out.println("输入交流电: 220V");
return 220;
}
}
创建适配器(Adapter)
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public int out() {
int output = adaptee.input() / 2;
System.out.println("输出交流电: " + output + "V");
return output;
}
}
客户端调用
public static void main(String[] args) {
Target adapter = new Adapter(new Adaptee());
int result = adapter.out();
System.out.println(result);
}
输入交流电: 220V
输出交流电: 110V
110
接口适配器
接口适配器的关注点与类适配器和对象适配器的关注点不太一样,类适配器和对象适配器着重于将系统存在的一个角色(Adaptee)转化成目标接口(Target)所需内容,而接口适配器的使用场景是解决接口方法过多,如果直接实现接口,那么类会多出许多空实现的方法,类显得很臃肿。此时,使用接口适配器就能让我们只实现我们需要的接口方法,目标更清晰。
接口适配器的主要原理就是原理利用抽象类实现接口,并且空实现接口众多方法。
创建目标角色(Target)
public interface Target {
int out1();
int out2();
int out3();
int out4();
}
创建源角色(Adaptee)
public class Adaptee{
public int input() {
System.out.println("输入交流电: 220V");
return 220;
}
}
创建适配器(Adapter)
public class Adapter implements Target {
protected Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
@Override
public int out1() {
int input220V = adaptee.input();
int output = input220V / 1;
System.out.println("输出交流电: " + output + "V");
return output;
}
@Override
public int out2() {
int input220V = adaptee.input();
int output = input220V / 2;
System.out.println("输出交流电: " + output + "V");
return output;
}
@Override
public int out3() {
return 0;
}
@Override
public int out4() {
return 0;
}
}
客户端调用
public static void main(String[] args) {
Target adapter = new Adapter(new Adaptee());
adapter.out1();
System.out.println("---------------------");
adapter.out2();
System.out.println("---------------------");
Target adapter2 = new Adapter(new Adaptee()) {
@Override
public int out3() {
int input220V = adaptee.input();
int output = input220V / 3;
System.out.println("输出交流电: " + output + "V");
return output;
}
};
adapter2.out3();
System.out.println("---------------------");
Target adapter3 = new Adapter(new Adaptee()) {
@Override
public int out4() {
int input220V = adaptee.input();
int output = input220V / 4;
System.out.println("输出交流电: " + output + "V");
return output;
}
};
adapter3.out4();
}
输入交流电: 220V
输出交流电: 220V
---------------------
输入交流电: 220V
输出交流电: 110V
---------------------
输入交流电: 220V
输出交流电: 73V
---------------------
输入交流电: 220V
输出交流电: 55V
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/136905.html