【设计模式系列】5.装饰器模式和适配器模式

目录

一、装饰器模式

二、适配器模式

1、类适配器

2、对象适配器

3、适配器模式的优缺点


一、装饰器模式

特点:

  • 在不改变一个对象本身功能的基础上给对象增加新的功能,即功能增强;
  • 如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是单继承机制,类适配器模式中,一次最多只能适配一个适配者类;
  • 对象适配器模式中,在适配器中置换适配者类的某些方法比较麻烦。

猜你喜欢

转载自blog.csdn.net/qq_29119581/article/details/114873409