设计模式-适配器模式
2019-05-26 本文已影响0人
境里婆娑
-
尽量少修改代码,通过扩展的方式解决了问题,这就是适配模式。
Convert the interface of a class into another interface clients expect.Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.(将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。)
适配器模式又叫做变压器模式,也叫做包装模式(Wrapper),但是包装模式可不止一个,还包括了装饰模式。
适配器通用类图

简单地说,适配器模式就是把一个接口或类转换成其他的接口或类,从另一方面来说,适配器模式也就是一个包装模式,为什么呢?它把Adaptee包装成一个Target接口的类,加了一层衣服。大家知道,设计模式原是为建筑设计而服务的,软件设计模式只是借用了人家的原理而已,那我们来看看最原始的适配器是如何设计的。
-
适配器简单例子
//目标类
public interface Target {
public void doSomeing();
}
//目标角色实现类
public class ConcreteTarget implements Target {
@Override
public void doSomeing() {
System.out.println("我是一个小小鸟...");
}
}
//原角色
public class Adaptee {
public void doAdd() {
System.out.println("我想飞的更高...");
}
}
//转换类
public class Adapter extends Adaptee implements Target {
@Override
public void doSomeing() {
super.doAdd();
}
}
//客户端
public class Client {
public static void main(String[] args) {
Target target = new ConcreteTarget();
target.doSomeing();
Target target1 = new Adapter();
target1.doSomeing();
}
}
-
适配器模式的优点
1.类的透明性
2.类的复用度
3.灵活性
-
使用场景
你有要修改一个已经投产中的接口时,适配器模式可能是最适合你的模式
-
适配器注意事项
设计阶段不要考虑,不是为了解决开发阶段问题,而是为了解决已经上生产项目问题
再次提醒一点,项目一定要遵守依赖倒置原则和里氏替换原则,否则即使在适合使用适配器的场合下,也会带来非常大的改造。
-
举个比较特殊的例子
原目标类有三个,目标类有一个
//源目标
public interface IBMWFactoryInfo {
//基本信息,比如什么车产地等
public Map getBMWCar();
}
//源目标
public interface IBenzFactoryInfo {
//基本信息,比如什么车类型等
public Map getBenzCar();
}
//源目标
public interface IAudiFactoryInfo {
//基本信息,比如什么车,轮胎、大小等
public Map getAudiCar();
}
//源目标实现类
public class BMWFactory implements IBMWFactoryInfo {
@Override
public Map getBMWCar() {
Map<String,String> map = new HashMap<String,String>();
map.put("place","Germany");
map.put("engine","v12");
return map;
}
}
//源目标实现类
public class BenzFactory implements IBenzFactoryInfo {
@Override
public Map getBenzCar() {
Map<String,String> map = new HashMap<String,String>();
map.put("model","S600");
map.put("engine","w12");
return map;
}
}
//源目标实现类
public class AudiFactory implements IAudiFactoryInfo {
@Override
public Map getAudiCar() {
Map<String,String> map = new HashMap<String,String>();
map.put("carname","Audi");
map.put("engine","v12");
return map;
}
}
//目标类
public interface CarInfo {
public String getCarName();
public String getCarEngien();
}
//转换类
public class AllCarFactory implements CarInfo {
//源目标对象
private IBMWFactoryInfo ibmwFactoryInfo = null;
private IBenzFactoryInfo iBenzFactoryInfo = null;
private IAudiFactoryInfo iAudiFactoryInfo = null;
//数据处理
private Map<String,String> bmwMap = null;
private Map<String,String> benzMap = null;
private Map<String,String> audiMap = null;
public AllCarFactory(IBMWFactoryInfo ibmwFactoryInfo, IBenzFactoryInfo iBenzFactoryInfo,
IAudiFactoryInfo iAudiFactoryInfo) {
this.ibmwFactoryInfo = ibmwFactoryInfo;
this.iBenzFactoryInfo = iBenzFactoryInfo;
this.iAudiFactoryInfo = iAudiFactoryInfo;
this.audiMap = iAudiFactoryInfo.getAudiCar();
this.benzMap = iBenzFactoryInfo.getBenzCar();
this.bmwMap = ibmwFactoryInfo.getBMWCar();
}
@Override
public String getCarName() {
return audiMap.get("carname");
}
@Override
public String getCarEngien() {
return audiMap.get("engine");
}
}
//客户端
public class Client {
public static void main(String[] args) {
IAudiFactoryInfo iAudiFactoryInfo = new AudiFactory();
IBenzFactoryInfo iBenzFactoryInfo = new BenzFactory();
IBMWFactoryInfo ibmwFactoryInfo = new BMWFactory();
AllCarFactory allCarFactory = new AllCarFactory(ibmwFactoryInfo,iBenzFactoryInfo,iAudiFactoryInfo);
System.out.println(allCarFactory.getCarEngien());
System.out.println(allCarFactory.getCarName());
}
}
运行结果

以上就是适配器的简单用法,欢迎大家指教,万分感谢