目录
一、装饰器模式
特点:
- 在不改变一个对象本身功能的基础上给对象增加新的功能,即功能增强;
- 如Java IO中的BufferedReader类就是对InputStreamReader类的包装或增强。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
举例:
假如xx去4S店买了一款领克01,它拥有领克车系的所有基础功能,但01却没有LED大灯,因此花点钱可以加装一个。
Demo实现:
/**汽车接口(抽象角色) */
public interface Car {
void getCarInfo();
}
/** 领克01车型(具体角色) */
public class LynkCar implements Car{
@Override
public void getCarInfo() {
System.out.println("领克车子的基本功能都有了~~~");
}
}
/**加装LED大灯(装饰角色) */
public class LynkCarDecorate implements Car {
// 通过构造器注入
private LynkCar lynkCar;
public LynkCarDecorate(LynkCar lynkCar) {
this.lynkCar = lynkCar;
}
// 加装LED大灯方法
public void addLedBulb() {
System.out.println("OK,已加装LED大灯");
}
// 增强原汽车的功能
@Override
public void getCarInfo() {
System.out.println("给领克车子加个LED大灯吧~~~");
this.addLedBulb();
}
}
测试:
@Test
void testDecorate() {
// 没有装饰器
// LynkCar lynkCar = new LynkCar();
// lynkCar.getCarInfo();
// 有装饰器
LynkCarDecorate lynkCarDecorate = new LynkCarDecorate(new LynkCar());
lynkCarDecorate.getCarInfo();
}
结果:
二、适配器模式
特点:
- 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,像插座转换器、USB转VGA的转接头,220V交流电转5V直流电等都属于生活中的适配器;
- 适配器(Adapter)有三种类型:类适配器模式(通过继承特性来实现适配器的功能)、对象适配器模式(通过对象组合方式来实现适配器的功能)、接口适配器模式(借助抽象类来实现适配器的功能);
- 适配器模式也是一种包装模式,具有包装的功能,实际中建议尽量使用对象的适配器模式。
1、类适配器
通过继承方式来实现适配器的功能。
举例:
不同品牌的手机充电接口是不同的,像苹果和华为分别采用的是苹果USB,type-c,为了在充电时满足不同品牌手机的需求,通过一个一线三拖的数据线可以解决这个问题,而这个一线三拖的数据线就是适配器角色。
Demo实现:
/** 苹果手机用苹果数据线 (被适配者)*/
class AppleUSB {
public void connection() {
System.out.println("使用苹果手机数据线连接...");
}
}
/** 定义目标接口,有数据线连接的功能 */
interface Target {
void connection();
}
/** 华为手机是type-c数据线 */
class HuaWeiUSB implements Target {
@Override
public void connection() {
System.out.println("使用华为手机type-c数据线连接...");
}
}
/** 开发一个一线三拖的数据线(适配器类),继承了被适配类,同时实现标准接口,实现不同USB都能使用 */
class OneToThreeAdapter extends AppleUSB implements Target {
@Override
public void connection() {
System.out.println("插入一线三拖数据线.....");
super.connection();
}
}
测试:
@Test
void testAdapter() {
Target target = new HuaWeiUSB();
target.connection();
Target adapter = new OneToThreeAdapter();
adapter.connection();
}
// 结果如下:
使用华为手机type-c数据线连接...
插入一线三拖数据线.....
使用苹果手机数据线连接...
2、对象适配器
对象适配器与类适配器不同之处在于,类适配器通过继承来完成适配,对象适配器则是通过对象关联来完成。改造上面的oneToThreeAdapter 类,只去实现接口,并将被适配者(苹果USB)作为该适配器的成员属性即可。
/** 一线三拖的数据线 */
class OneToThreeAdapter implements Target {
// 将被适配者作为成员属性
private AppleUSB apple = new AppleUSB();
@Override
public void connection() {
System.out.println("插入一线三拖数据线.....");
apple.connection();
}
}
3、适配器模式的优缺点
总结下适配器模式的优点:
- 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构;
- 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用;
- 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”
当然,它也是有缺点的:
- Java是单继承机制,类适配器模式中,一次最多只能适配一个适配者类;
- 对象适配器模式中,在适配器中置换适配者类的某些方法比较麻烦。