原创

JAVA设计模式(篇五)

温馨提示:
本文最后更新于 2022年10月27日,已超过 918 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

七-适配器模式

在现实生活中,经常出现两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。比如我有一副扁口苹果耳机,但是想在安卓手机上(圆口)听歌,此时再买一个类似的高质量耳机花费太高,仅需买一个耳机转接头即可解决问题。
在软件设计中也可能出现: 需要开发的具有某种业务功能的组件在现有的组件库中已经存在,但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题。

1.模式的定义与特点

1. 适配器模式定义:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

2. 优点

  • 客户端通过适配器可以透明地调用目标接口。
  • 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
  • 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。

3. 缺点:

  • 对类适配器来说,更换适配器的实现过程比较复杂。

2. 模式的结构和实现

适配器模式由,目标接口适配者适配器三大模块组成

1. 模式的结构

  • 目标(Target)接口: 当前系统业务所期待的接口,它可以是抽象类或接口。
  • 适配者(Adaptee)类: 它是被访问和适配的现存组件库中的组件接口。
  • 适配器(Adapter)类: 它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

类适配器结构图:

image-20220804163117444

对象适配器结构图:

image-20220804163158761

2.模式的实现

1.类适配器实现
//目标接口 充电
public interface TargetCharge {
    void charge();
}
//适配者(华为充电器)
public class AdapeeHWCharger {

    void hwCharge(){
        System.out.println("华为充电器充电成功");
    }
}
//适配器(数据线转接头 苹果转华为 )
public class Adapter extends AdapeeHWCharger implements TargetCharge{

    @Override
    public void charge() {
        hwCharge();
    }
}
//测试
@Test
void adapter(){
    System.out.println("使用转接头让华为充电器能充苹果手机的电");
    Adapter adapter = new Adapter();
    adapter.charge();
}
2.对象适配器实现
//目标接口 充电
public interface TargetCharge {
    void charge();
}
//适配者(华为充电器)
public class AdapeeHWCharger {

    void hwCharge(){
        System.out.println("华为充电器充电成功");
    }
}
//适配器(数据线转接头 苹果转华为 )
public class AdapterObject implements TargetCharge{

    private AdapeeHWCharger  adapeeHWCharger;

    public AdapterObject(AdapeeHWCharger  adapeeHWCharger){
        this.adapeeHWCharger = adapeeHWCharger;
    }

    @Override
    public void charge() {
        this.adapeeHWCharger.hwCharge();
    }
}
//测试使用
@Test
void adapterObject(){
    System.out.println("使用转接头让华为充电器能充苹果手机的电");
    AdapeeHWCharger adapeeHWCharger = new AdapeeHWCharger();//生成适配者
    AdapterObject adapterObject = new AdapterObject(adapeeHWCharger);//设配器初始化时加入设配者
    adapterObject.charge();
}

TIPS: 适配器模式的核心就是,适配器实现目标接口,在适配器中调用适配者的方法。

3.模式的应用场景

  • 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
  • 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。

八-桥接模式

在现实生活中,某些类具有两个或多个维度的变化,如服装可以根据颜色来区分,也可以根据类别来区分。如果用继承方式,有m种颜色和n种类别,对应的子类就是m*n种,不仅子类繁多,而且扩展困难。此时使用桥接模式即可很好的解决问题。

1.模式的定义与特点

桥接(Bridge)模式: 将抽象实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

优点:

  • 由于抽象与实现分离,所以扩展能力强;
  • 其实现细节对客户透明

缺点:

  • 由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,这增加了系统的理解与设计难度。

2.模式的结构和实现

1.桥接模式的结构

  • 抽象化(Abstraction) 角色: 定义抽象类,并包含一个对实现化对象的引用。
  • 扩展抽象化(Refined Abstraction)角色: 是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  • 实现化(Implementor) 角色: 定义实现化角色的接口,供扩展抽象化角色调用。
  • 具体实现化(Concrete Implementor)角色: 给出实现化角色接口的具体实现。

结构图

image-20220804173851270

Tips:以实现为例

抽象化(Abstraction) 角色:对应服装,包含了颜色。

扩展抽象化(Refined Abstraction)角色:对应具体服装,如上衣,裤子等,包含颜色。

实现化(Implementor) 角色:对应颜色,提供给服装引用

具体实现化(Concrete Implementor)角色: 具体颜色,如红色,蓝色,黄色等

一个抽象化角色可以有多个扩展抽象化角色(m种类别),一个抽象化角色还可以包含多个实现化角色,实现复杂的扩展

实现化角色可以有多种具体实现化角色(n种颜色)

2.桥接模式的实现

//实现化角色  (颜色)
public interface ImplementorColor {

    void showCreateColor();
}
//具体实现化角色  (蓝色)
public class ImplementorColorBlue implements ImplementorColor {

    @Override
    public void showCreateColor() {
        System.out.println("生产的颜色为:蓝色");
    }
}
//具体实现化角色  (红色)
public class ImplementorColorRed implements ImplementorColor {


    @Override
    public void showCreateColor() {
        System.out.println("生产的颜色为:红色");
    }
}

//抽象化角色 (衣服)
public abstract class AbstractClothes {

    public ImplementorColor implementorColor;

    public AbstractClothes(ImplementorColor implementorColor){
        this.implementorColor = implementorColor;
    }
    //展示被创建的衣服信息
    public void showCreateClothes(){}
}
//扩展抽象化角色 (上衣)
public class RefindAbstractJacket extends AbstractClothes{
    public RefindAbstractJacket(ImplementorColor implementorColor) {
        super(implementorColor);
    }

    @Override
    public void showCreateClothes() {
        implementorColor.showCreateColor();
        System.out.println("生产的衣服类别为:上衣");
    }
}

//扩展抽象化角色 (裤子)
public class RefindAbstractTrousers extends AbstractClothes{
    public RefindAbstractTrousers(ImplementorColor implementorColor) {
        super(implementorColor);
    }

    @Override
    public void showCreateClothes() {
        System.out.println("生产的衣服类别为:裤子");
    }
}
//测试
@Test
void bridge(){
    ImplementorColor color = new ImplementorColorBlue();//生成一个具体实现化角色(指定什么颜色:蓝色)
    AbstractClothes clothes = new RefindAbstractJacket(color);//生成一个扩展抽象化角色(指定服装的类别:上衣)
    clothes.showCreateClothes();
}
//输出为
生产的颜色为:蓝色
生产的衣服类别为:上衣

3. 桥接模式的应用场景

  • 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
  • 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
  • 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。

4.桥接模式的扩展

在软件开发中,有时桥接(Bridge)模式可与适配器模式联合使用。当桥接(Bridge)模式的实现化角色的接口与现有类的接口不一致时,可以在二者中间定义一个适配器将二者连接起来,结构图如下 :

image-20220804175930068

代码实现

//适配者(红蓝相间)
public class AdapteeRedBlue {

    public void showColor(){
        System.out.println("生成的颜色:红蓝相间");
    }

}

//对象适配器 适配颜色
public class AdapaterColorObject implements ImplementorColor{

    private AdapteeRedBlue adapteeRedBlue;

    public AdapaterColorObject(AdapteeRedBlue adapteeRedBlue){
        this.adapteeRedBlue = adapteeRedBlue;
    }

    @Override
    public void showCreateColor() {
        adapteeRedBlue.showColor();
    }
}

//其他代码和上面的一样
//测试
@Test
void bridgeAndAdapter(){
    AdapteeRedBlue adapteeRedBlue = new AdapteeRedBlue();//生成适配者(红蓝相间)
    ImplementorColor color = new AdapaterColorObject(adapteeRedBlue);//生成具体实现化角色,此时该角色是由适配器生成的。
    AbstractClothes clothes = new RefindAbstractJacket(color);//生成一个扩展抽象化角色(指定服装的类别:上衣)
    clothes.showCreateClothes();
}
//输出
生成的颜色:红蓝相间
生产的衣服类别为:上衣
正文到此结束