您的位置:首页 > 编程语言 > Java开发

Java设计模式之适配器模式

2016-09-21 00:32 417 查看

Java设计模式之适配器模式

适配器模式介绍

  适配器模式在我们的项目开发中使用效率也非常高,尤其最为熟悉的,在android中,无论是我们的ListView,GridView,还是到现在最新用的RecyclerView都需要用到Adapter。适配器是将两个不兼容的类融合在一起,他有点像粘合剂,将不同的东西通过一种转换使得他们能够协作起来。例如,经常碰到要再来年各个没有关系的类型之间进行交互,第一个解决方案就是修改他们各自类的接口,但是如果没有源代码或者我们不愿意为了一个应用而修改各自的接口,此时怎么办?这种情况我们往往会使用一个Adapter,在这两种接口之间创建一个转换接口,这个Adapter会将这两个接口进行兼容,在不修改源代码的情况下满足要求。

  

适配器模式的定义

  

  将一个类的接口转换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够再一起工作。

  

适配器模式的使用场景

  1.系统需要使用现有的类,而此类的接口不符合系统的需求,即接口不兼容

  2.想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作

  3.需要一个统一的输出接口,而输入端的类型不可预知

适配器模式的UML图



Target:目标角色,也就是所期待得到的接口。注意:由于这里讨论的是类适配器模式,因此目标不可以是类。

Adaptee:源角色,现在需要适配的接口。

Adapter : 适配器角色,也就是本模式的核心。适配器把源接口转换成目标接口。显然这一角色不可以是接口,而必须是具体的类。

适配器模式的简单用例

  就用电源做一个小例子,笔记本的电源一般都是用5V的电压,而成活中的电线电压一般都是220V。这个时候就出现了不匹配的情况,在软件开发中我们称之为接口不兼容,此时就需要适配器进行一个接口转换。

FiveVolt.java

/**
* Target角色
*/
public interface FiveVolt {
int getVoltFive();
}


Volt220.java

/**
* Adaptee角色,需要被转换的对象
*/
public class Volt220 {
public int getVolt220(){
return 220;
}
}


VoltAdapter.java

/**
* Adapter角色,将220V的电压转换成5V的电压
*/
public class VoltAdapter extends Volt220 implements FiveVolt {
@Override
public int getVoltFive() {
return 5;
}
}


Test.java

/**
* 测试类,通过适配器,我们可以获取5V的电压
*/
public class Test {
public static void main(String[] args) {
VoltAdapter adapter = new VoltAdapter();
System.out.println("输出电压" + adapter.getVoltFive() + "V");
}
}


在上面的几个类中,Target角色,也就是我们的FiveVolt,为我们提供了需要的目标接口,而Adaptee,Volt220类则是需要被转换的对象。Adapter VoltAdapter类则是将Volt220转换成FiveVolt的接口,对应的Target的目标就是要获取5V的输出电压,而Adaptee正常输出电压是220V,此时就需要电源适配器类将220V的电压转换为5V电压,解决了接口不兼容问题。

对于上面这个问题,我们就是这样解决的,那么又有一个问题来了,如果说,我们不仅只要将220V转换成5V的电压,对于其他电器,我们也需要进行转换,比如,手机的电池一般3-5V,这里我们假设手机需要220V转换成3V,平板需要将电压转换成4V,那这个时候我们就不能使用上面的方法了,因为我们都知道,Java不支持多继承。那么该怎么实现呢?首先你不可能去继承三个实现类吧,此路不通,再想一个办法,没错,就是可以使用关联类的方法来实现了,下面看看代码的具体实现吧。

三个Target角色

FiveVolt.java

public interface FourVolt {
int getFourVolt();
}


ThreeVolt.java

public interface ThreeVolt {
int getThreeVolt();
}


FourVolt.java

public interface FourVolt {
int getFourVolt();
}


三个具体的实现类

ComputerFiveVolt.java

public class ComputerFiveVolt implements FiveVolt {
@Override
public int getVoltFive() {
return 5;
}
}


PhoneThreeVolt.java

public class PhoneThreeVolt implements ThreeVolt {
@Override
public int getThreeVolt() {
return 3;
}
}


IpadFourVolt.java

public class IpadFourVolt implements FourVolt {
@Override
public int getFourVolt() {
return 4;
}
}


VoltAdapter.java

/**
* Adapter角色,将220V的电压转换成5V,4V,3V的电压
*/
public class VoltAdapter extends Volt220 {
private FourVolt fourVolt;
private FiveVolt fiveVolt;
private ThreeVolt threeVolt;

public VoltAdapter(FiveVolt fiveVolt, FourVolt fourVolt, ThreeVolt threeVolt) {
this.threeVolt = threeVolt;
this.fourVolt = fourVolt;
this.fiveVolt = fiveVolt;
}

public int getIpadFourVolt() {
int volt = getVolt220();
System.out.println("源电压为:" + volt);
System.out.println("开始转换");
volt = fourVolt.getFourVolt();
return volt;
}

public int getComputerFiveVolt() {
int volt = getVolt220();
System.out.println("源电压为:" + volt);
System.out.println("开始转换");
volt = fiveVolt.getVoltFive();
return volt;
}

public int getPhoneThreeVolt() {
int volt = getVolt220();
System.out.println("源电压为:" + volt);
System.out.println("开始转换");
volt = threeVolt.getThreeVolt();
return volt;
}
}


Test.java

/**
* 测试类,通过适配器,我们可以获取5V、3V、4V的电压
*/
public class Test {
public static void main(String[] args) {
FiveVolt fiveVolt = new ComputerFiveVolt();
FourVolt fourVolt = new IpadFourVolt();
ThreeVolt threeVolt = new PhoneThreeVolt();
VoltAdapter adapter = new VoltAdapter(fiveVolt,fourVolt,threeVolt);
System.out.println("电脑输出电压" + adapter.getComputerFiveVolt() + "V");
System.out.println("手机输出电压" + adapter.getPhoneThreeVolt() + "V");
System.out.println("IPAD输出电压" + adapter.getIpadFourVolt() + "V");
}
}


输出结果:

源电压为:220
开始转换
输出电压220V转换为电脑电池5V
源电压为:220
开始转换
输出电压220V转换为手机电池3V
源电压为:220
开始转换
输出电压220V转换为IPAD电池4V


这样就完全解决了我们有多个目标接口,实现转换的问题了。

通过上面的对适配器模式的介绍,来总结一下适配器模式的优点有哪些

1.适配器模式可以让两个或者多个没有任何关系的类在一起运行,只要适配器这个角色能够搞定他们就成。

2.增加了类的透明性 ,我们访问的Target角色,但是具体的实现都委托个了源角色,而这些对高层次模块是透明的,也是它不需要关心的。

3.提高了类的复用度 源角色在原有的系统中还是可以正常使用,而在目标角色中也充当了新的演远。

4.灵活性非常好

比如,哪一次,我们不需要适配器角色了,那么直接删除就行了,其他的代码都不用修改,基本上就类似一个灵活的构建,想用就用,不想用就卸载。

适配器模式的注意事项:

适配器模式最好在详细设计阶段不要考虑它,它不是为了解决还在处于开发阶段的问题,而是解决正在服役的项目问题,没有一个系统设计师会在做详细设计的时候考虑使用适配器模式,这个模式使用的主要场景是扩展应用。

并且,对于项目一定要遵守依赖倒置和里氏替换原则,否则即使在使用适配器的场合下,也会带来非常大的改造。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: