1、什么是适配器模式java
适配器这个词咱们应该很熟悉,每天都在使用,手机充电时,电源线头头就叫电源适配器,干什么用的呢?把220V电压转换成手机充电时使用的电压,那么适配器是否是很好理解了,下面看一下定义。ide
Adapter适配器模式,将一个类的接口转换成客户但愿的另一个接口。使本来因为接口不兼容而不能一块儿工做的那些类能够一块儿工做了。测试
适配器模式有“类适配器”和“对象适配器”两种不一样的形式。this
2、类适配器spa
经过继承进行适配(类间继承)。URL结构图以下:翻译
一、Target设计
Target目标角色,该角色定义把其它类转换成指望接口,一般状况下是一个接口或一个抽象类,通常不会是实现类。3d
public interface Target { public void request(); }
二、Adapteecode
Adaptee源角色,想把谁转换为目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类或对象。对象
public class Adaptee { public void specificRequest() { System.out.println("特殊请求"); } }
三、Adapter
Adapter适配器角色,是适配器模式的核心角色,它的职责是经过继承或类关联的方式把源角色转换成目标角色。
public class Adapter extends Adaptee implements Target { @Override public void request() { super.specificRequest(); } }
四、ConcreteTarget
package designMode.adapter.sxn; public class ConcreteTarget implements Target { @Override public void request() { System.out.println("普通请求"); } }
五、测试类
package designMode.adapter.sxn; public class Client { public static void main(String[] args) { //原有业务逻辑 Target target = new ConcreteTarget(); target.request(); //增长适配器后的业务逻辑 Target target2 = new Adapter(); target2.request(); } }
六、输出结果:
3、对象适配器
经过对象层次的关联关系进行委托(对象的合成关系/关联关系)。UML结构图以下:
一、Target
客户所期待的接口。目标能够是具体的或抽象的类,也能够是接口。
package designMode.adapter.sxn; public class Target { public void request() { System.out.println("普通请求"); } }
二、Adaptee
须要适配的类。
package designMode.adapter.sxn; public class Adaptee { public void specificRequest() { System.out.println("特殊请求"); } }
三、Adapter
经过在内部包装一个Adaptee对象,把源接口转换成目标接口。
package designMode.adapter.sxn; public class Adapter extends Target{ private Adaptee adaptee = new Adaptee(); @Override public void request() { adaptee.specificRequest(); } }
四、测试类
package designMode.adapter.sxn; public class Client { public static void main(String[] args) { Target target = new Adapter(); target.request(); } }
五、输出结果
4、适配器模式的应用
一、什么时候使用
(1)系统须要使用现有的类,从而类的接口不符合系统的须要。
(2)想创建一个能够重复使用的类,用于一些彼此之间没有太大关联的一些类。
(3)经过接口转换,将一个类插入另外一个类中。
二、方法
继承或依赖。
三、优势
(1)可让任何两个没有关联的类一块儿运行。
(2)增长了类的透明性。
咱们访问target目标角色,但具体实现都委托给了源角色,而这些对高层模块是透明的,也是不须要关心的。
(3)提升了类的复用度。
源角色在原有的系统中仍是能够正常使用,而在目标角色中也能够充当新的演员。
(4)灵活性很是好。
何时不想要适配器了,直接删掉就能够了。
四、缺点
(1)过多使用适配器会使系统很是凌乱。
(2)因为java是单继承的,因此只能适配一个适配器类,并且目标类必须是抽象的。
五、注意事项
只有碰到没法改变原有设计和代码的状况下,才会考虑适配器模式。
5、适配器模式的实现
下面咱们以翻译官为例,姚明刚去美国时,不懂英文,专门为他配备了翻译,特别是在比赛场上,教练、队员与他的对话所有都经过翻译来沟通,这里翻译就是适配器。如今编写一个适配器模式的例子,火箭队比赛,教练叫暂停时给后卫、中锋、前锋分配进攻和防守任务。UML图以下:
一、Player类
抽象球员类,有进攻和防守两种方法。
package designMode.adapter; public abstract class Player { protected String name; public Player(String name) { this.name = name; } public abstract void attack(); //进攻 public abstract void defense(); //防守 }
二、前锋、中锋、后卫类
重写了Player类中的进攻和防守两个方法,此时是英文的,还没有翻译。
package designMode.adapter; public class Forwards extends Player{ public Forwards(String name) { super(name); } @Override public void attack() { System.out.println("Forward " + name + " attack"); } @Override public void defense() { System.out.println("Forward " + name + " defense"); } }
package designMode.adapter; public class Guards extends Player { public Guards(String name) { super(name); } @Override public void attack() { System.out.println("Forward " + name + " attack"); } @Override public void defense() { System.out.println("Forward " + name + " defense"); } }
三、ForeignCenters类
外籍中锋类。只能听懂中文。
package designMode.adapter; public class ForeignCenters { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void attackChi() { System.out.println("中锋 " + name + " 进攻"); } public void defenseChi() { System.out.println("中锋 " + name + " 防守"); } }
四、Translator类
翻译者类,也就是适配器。对英文的进攻和防守进行翻译。
package designMode.adapter; public class Translator extends Player{ private ForeignCenters foreignCenter = new ForeignCenters(); public Translator(String name) { super(name); foreignCenter.setName(name); } @Override public void attack() { foreignCenter.attackChi(); } @Override public void defense() { foreignCenter.defenseChi(); } }
五、测试类
package designMode.adapter; public class Client { public static void main(String[] args) { Player bPlayer = new Forwards("杜兰特"); bPlayer.attack(); Player mPlayer = new Guards("麦克格雷迪"); mPlayer.attack(); Player yPlayer = new Translator("姚明"); yPlayer.attack(); yPlayer.defense(); } }
六、运行结果
6、类适配器和对象适配器的区别
从上面的内容能够看出,类适配器是类间继承,对象适配器是对象的合成关系,也能够说是类的关联关系,这是二者的根本区别。
因为对象适配器是经过类间的关联关系进行耦合的,所以在设计时就能够作到比较灵活,而类适配器就只能经过覆写源角色的方法进行扩展。
在实际项目中,对象适配器使用的场景较多。
每一篇博客都是一种经历,程序猿生涯的痕迹,知识改变命运,命运要由本身掌控,愿你游历半生,归来还是少年。
欲速则不达,欲达则欲速!
更多精彩内容,首发公众号【素小暖】,欢迎关注。