Java Design Patterns - Structural Design Pattern (Adapter Design Pattern)

Introduction

1、⻅名知意,是作为两个不兼容的接⼝之间的桥梁,属于结构型模式
2、适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作

Common types of adapters

class adapter pattern

想将⼀个类转换成满⾜另⼀个新接⼝的类时,可以使⽤类的适配器模式,创建⼀个新类,继承原有的类,实现新的接⼝即可

Object Adapter Pattern

想将⼀个对象转换成满⾜另⼀个新接⼝的对象时,可以创建⼀个适配器类,持有原类的⼀个实例,在适配器类的⽅法中,调⽤实例的⽅法就⾏

Adapter mode of the interface

不想实现⼀个接⼝中所有的⽅法时,可以创建⼀个Adapter,实现所有⽅法,在写别的类的时候,继承Adapter类即

Application scenarios

1. The computer needs to read the data of the memory card, and the card reader is the adapter.
2. Daily-used adapters, such as power adapters and voltage adapters.
3. The system needs to use existing classes, and the interfaces of these classes Does not meet the needs of the system
4. InputStreamReader in JDK is the adapter
5. JDBC is the adapter mode we use most

JDBC给出⼀个客户端通⽤的抽象接⼝,每⼀个具体数据库⼚商 如 SQL ServerOracleMySQL等,就会开发JDBC驱动,就是⼀个介于JDBC接⼝和数据库引擎接⼝之间的适配器软件

Insert image description here

Improve development efficiency and application of interface adapters in daily development

Interface adapter

有些接⼝中有多个抽象⽅法,当我们写该接⼝的实现类时,必须实现该接⼝的所有⽅法,这明显有时⽐较浪费,因为并不是所有的⽅法都是我们需要的,有时只需要实现部分接⼝就可以了

For demo,
I don’t want to implement all interfaces, but only want to rewrite some interfaces.

original interface

public interface PayGateway {
    
    

    /**
     * 下单
     */
    void unifiedorder();

    /**
     * 退款
     */
    void refund();

    /**
     * 查询支付状态
     */
    void query();

    /**
     * 发红包
     */
    void sendRedPack();
}

adapter

public class PayGatewayAdapter implements PayGateway {
    
    

    @Override
    public void unifiedorder() {
    
    

    }

    @Override
    public void refund() {
    
    

    }

    @Override
    public void query() {
    
    

    }

    @Override
    public void sendRedPack() {
    
    

    }
}

Use some interfaces

public class ProductVideoOrder extends PayGatewayAdapter {
    
    

    @Override
    public void unifiedorder() {
    
    
        System.out.println("ProductVideoOrder unifiedorder");
    }

    @Override
    public void refund() {
    
    
        System.out.println("ProductVideoOrder refund");
    }
}

Add new methods using some interfaces

public class ProductVipOrder extends PayGatewayAdapter {
    
    

    @Override
    public void unifiedorder() {
    
    
        System.out.println("ProductVipOrder unifiedorder");
    }

    @Override
    public void refund() {
    
    
        System.out.println("ProductVipOrder refund");
    }

    @Override
    public void sendRedPack() {
    
    
        System.out.println("ProductVipOrder sendRedPack");
    }
}

Production environment interface-what should I do if I need to be compatible with new businesses?

Demand background

有个电商⽀付项⽬,⾥⾯有个登录功能,已经线上运⾏了
客户端A 调⽤⽣产环境的登录接⼝B,且线上稳定运⾏了好⼏年。某天,公司接到收购了别的公司的项⽬,需要把这套系统部署在起来,且收购的项⽬也有对应的客户端C,但是两个客户端和服务端的协议不⼀样
需求:收购的项⽬客户端C,需要做公司原来的项⽬⽤户数据打通,连接公司的服务端登录接⼝B,你能想到⼏个解决⽅案?
1、修改就项⽬B的登录接⼝,兼容C客户端协议(可能影响线上接⼝,不稳定)
2、新增全新的登录接⼝F,采⽤C客户端协议(和旧的业务逻辑会重复)
3、新增⼀个转换协议接⼝,客户端C调⽤旧的B接⼝之前,使⽤转换接⼝转换下协议(适配器模式,推荐这个⽅式)

Insert image description here
Summarize

1、在使⽤⼀些旧系统或者是类库时,经常会出现接⼝不兼容的问题,适配器模式在解决这类问题具有优势
2、学习设计模式⼀定不要局限代码层⾯,要从软件系统整体去考虑,⽽不是为了使⽤设计模式,⽽去使⽤设计模式

advantage

1、可以让任何两个没有关联的类⼀起运⾏,使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作
2、增加灵活度, 提⾼复⽤性,适配器类可以在多个系统使⽤,符合开闭原则

shortcoming

整体类的调⽤链路增加,本来A可以直接调⽤C,使⽤适配器后 是A调⽤BB再调⽤C

Adapter design pattern - class adapter

Introduction

想将⼀个类转换成满⾜另⼀个新接⼝的类时,可以使⽤类的适配器模式,创建⼀个新类,继承原有的类,实现新的接⼝即可

Insert image description here
demo

old primitive class

public class OldModule {
    
    

    public void methodA(){
    
    
        System.out.println("OldModule methodA");
    }
}

new target interface

public interface TargetModule {
    
    

    /**
     * 和需要适配的类方法名一样
     */
    void methodA();

    /**
     * 新的方法,如果有多个新的方法直接编写就行
     */
    void methodB();

    void methodC();

}

adapter

public class Adapter extends OldModule implements TargetModule {
    
    

    /**
     * 新的方法,和老的类方法不一样
     */
    @Override
    public void methodB() {
    
    
        System.out.println("Adapter methodB");
    }

    /**
     * 新的方法,和老的类方法不一样
     */
    @Override
    public void methodC() {
    
    
        System.out.println("Adapter methodC");
    }
}

test

public class Main {
    
    

    public static void main(String[] args) {
    
    
        TargetModule targetModule = new Adapter();
        targetModule.methodA();
        targetModule.methodB();
        targetModule.methodC();
    }
}

result

0ldModule methodA
Adapter methodB
Adapter methodC

Guess you like

Origin blog.csdn.net/csdn_mycsdn/article/details/129357700