Modo de adaptador del modo de diseño de Java (Adaptador)

concepto

GOF define el patrón de adaptador ( Adapter) de esta manera: convierte la interfaz de una clase en otra interfaz que el usuario necesita. El patrón Adapter permite que las clases que de otro modo no funcionarían juntas debido a interfaces incompatibles trabajen juntas.

En GOF, el patrón de adaptador se divide en patrón de adaptador de clase y patrón de adaptador de objeto. La única diferencia es si la adaptación del rol del adaptador al rol adaptado se realiza mediante herencia o composición. Porque la herencia múltiple no es compatible con Java y se sospecha que rompe la encapsulación. Y también defendemos [combinaciones múltiples y menos herencia][2]. Así que este artículo presenta principalmente el adaptador de objetos.

usar

Creo que todo el mundo tiene este sentido común de la vida: los modelos de cargadores de dispositivos electrónicos que usamos son diferentes. Los principales puertos de carga de teléfonos móviles actuales incluyen principalmente Mini Usb, Micro Usb y Lightning. Entre ellos, Mini Usb aparece ampliamente en lectores de tarjetas, MP3, cámaras digitales y discos duros móviles. Debido a que Micro Usb es más delgado que Mini Usb, es ampliamente utilizado en teléfonos móviles, común en teléfonos Android. Otro puerto de carga común es Lightning, que se usa comúnmente en los teléfonos móviles de Apple.

Por supuesto, ciertos modelos de teléfonos solo se pueden cargar con ciertos modelos de cargadores. Por ejemplo, el iPhone 6 solo se puede cargar con un cargador con interfaz Lightning. Sin embargo, si solo tenemos un cable cargador Android Micro Usb a nuestro alrededor, ¿podemos cargar teléfonos Apple? La respuesta es sí, siempre que haya un adaptador.

adaptador

Los adaptadores se pueden ver en todas partes en nuestra vida diaria. El patrón del adaptador es exactamente para resolver un problema similar.

También podemos encontrar escenarios similares durante el proceso de diseño del programa:

1. El sistema necesita usar clases existentes y dichas interfaces no satisfacen las necesidades del sistema.

2. Quiero crear una clase reutilizable para trabajar con algunas clases que no están muy relacionadas entre sí, incluidas algunas clases que pueden introducirse en el futuro.Estas clases fuente no necesariamente tienen una interfaz consistente.

3. Insertar una clase en otro sistema de clases a través de la conversión de interfaz. (Por ejemplo, tigres y pájaros, ahora hay un tigre volador. Sin aumentar los requisitos de la entidad, agregue un adaptador que contenga un objeto de tigre y realice la interfaz de vuelo).

Los escenarios anteriores son adecuados para usar el patrón de adaptador.

Método para realizar

El patrón de adaptador incluye los siguientes roles:

Destino: clase abstracta de destino

Adaptador: clase de adaptador

Adaptado: clase de adaptador

Cliente: clase de cliente

Patrón de adaptador

Aquí usamos el ejemplo del puerto de carga del teléfono móvil presentado al principio del artículo, definimos un adaptador cuya función es usar el cargador de Android para cargar el dispositivo Apple.

Primero defina la interfaz:

/**
 * MicroUsb充电器接口
 */
public interface MicroUsbInterface {
    public void chargeWithMicroUsb();
}

/**
 * Lightning充电器接口
 */
public interface LightningInterface {
    public void chargeWithLightning();
}

Definir una clase de implementación concreta

/**
 * 安卓设备的充电器
 */
public class AndroidCharger implements MicroUsbInterface {
    @Override
    public void chargeWithMicroUsb() {
        System.out.println("使用MicroUsb型号的充电器充电...");
    }
}

/**
 * 苹果设备的充电器
 */
public class AppleCharger implements LightningInterface {
    @Override
    public void chargeWithLightning() {
        System.out.println("使用Lightning型号的充电器充电...");
    }
}

Debido a que queremos usar el modo de adaptador para convertir MicroUsb a Lightning, no es necesario definir AppleCharger aquí. Porque nuestro propósito de usar el adaptador es reemplazar uno nuevo. Se define aquí para hacer el ejemplo más completo.

definir dos teléfonos

public class Iphone6Plus {

    private LightningInterface lightningInterface;

    public Iphone6Plus() {
    }

    public Iphone6Plus(LightningInterface lightningInterface) {
        this.lightningInterface = lightningInterface;
    }

    public void charge() {
        System.out.println("开始给我的Iphone6Plus手机充电...");
        lightningInterface.chargeWithLightning();
        System.out.println("结束给我的Iphone6Plus手机充电...");
    }

    public LightningInterface getLightningInterface() {
        return lightningInterface;
    }

    public void setLightningInterface(LightningInterface lightningInterface) {
        this.lightningInterface = lightningInterface;
    }
}

public class GalaxyS7 {

    private MicroUsbInterface microUsbInterface;

    public GalaxyS7() {
    }

    public GalaxyS7(MicroUsbInterface microUsbInterface) {
        this.microUsbInterface = microUsbInterface;
    }

    public void charge(){
        System.out.println("开始给我的GalaxyS7手机充电...");
        microUsbInterface.chargeWithMicroUsb();
        System.out.println("结束给我的GalaxyS7手机充电...");
    }

    public MicroUsbInterface getMicroUsbInterface() {
        return microUsbInterface;
    }

    public void setMicroUsbInterface(MicroUsbInterface microUsbInterface) {
        this.microUsbInterface = microUsbInterface;
    }
}

El papel del teléfono móvil se define aquí para una comprensión más conveniente del modo adaptador, en el que no juega ningún papel.

Definir el adaptador

/**
 * 适配器,将MicroUsb接口转成Lightning接口
 */
public class Adapter implements LightningInterface {
    private MicroUsbInterface microUsbInterface;

    public Adapter() {
    }

    public Adapter(MicroUsbInterface microUsbInterface) {
        this.microUsbInterface = microUsbInterface;
    }

    @Override
    public void chargeWithLightning() {
        microUsbInterface.chargeWithMicroUsb();
    }

    public MicroUsbInterface getMicroUsbInterface() {
        return microUsbInterface;
    }

    public void setMicroUsbInterface(MicroUsbInterface microUsbInterface) {
        this.microUsbInterface = microUsbInterface;
    }
}

La función de este adaptador es convertir un MicroUsb en Lightning. El método de implementación es implementar la interfaz ( LightningInterface) de la clase de destino y luego usar el método combinado para definir microUsb en el adaptador. Luego, en el método reescrito chargeWithLightning(), use el método de microUsb para darse cuenta de los detalles específicos.

definir cliente

public class Main {

    public static void main(String[] args) {
        Iphone6Plus iphone6Plus = new Iphone6Plus(new AppleCharger());
        iphone6Plus.charge();

        System.out.println("==============================");

        GalaxyS7 galaxyS7 = new GalaxyS7(new AndroidCharger());
        galaxyS7.charge();

        System.out.println("==============================");

        Adapter adapter  = new Adapter(new AndroidCharger());
        Iphone6Plus newIphone = new Iphone6Plus();
        newIphone.setLightningInterface(adapter);
        newIphone.charge();
    }
}

Resultado de salida:

开始给我的Iphone6Plus手机充电...
使用Lightning型号的充电器充电...
结束给我的Iphone6Plus手机充电...
==============================
开始给我的GalaxyS7手机充电...
使用MicroUsb型号的充电器充电...
结束给我的GalaxyS7手机充电...
==============================
开始给我的Iphone6Plus手机充电...
使用MicroUsb型号的充电器充电...
结束给我的Iphone6Plus手机充电...

El ejemplo anterior utiliza un cargador tipo MicroUsb para cargar un Iphone a través de un adaptador. Desde el nivel de código, la interfaz MicroUsb y su clase de implementación se reutilizan a través del adaptador. El código existente se reutiliza en gran medida.

Ventajas y desventajas

ventaja

Desacople la clase de destino y la clase de adaptador, y reutilice la clase de adaptador existente introduciendo una clase de adaptador sin modificar el código original.

La transparencia y la reutilización de la clase aumentan, y la implementación específica se encapsula en la clase del adaptador, que es transparente para la clase del cliente y mejora la reutilización del adaptador.

La flexibilidad y la escalabilidad son muy buenas. Al usar el archivo de configuración, el adaptador se puede reemplazar fácilmente y se puede agregar una nueva clase de adaptador sin modificar el código original, lo que cumple completamente con el "principio de abrir y cerrar".

defecto

El uso excesivo de adaptadores hará que el sistema sea muy desordenado y difícil de comprender en su conjunto. Por ejemplo, es obvio que se llama a la interfaz A, pero la implementación interna en realidad está adaptada a la implementación de la interfaz B. Si esto sucede demasiado en un sistema, equivale a un desastre. Por lo tanto, si no es necesario, puede refactorizar directamente el sistema sin usar el adaptador.

Para los adaptadores de clase, dado que JAVA hereda como máximo una clase, como máximo se puede adaptar una clase de adaptador y la clase de destino debe ser una clase abstracta

Resumir

Los patrones estructurales describen cómo las clases u objetos se agrupan para formar estructuras más grandes.

El patrón de adaptador se usa para convertir una interfaz en otra interfaz que el cliente quiera.El patrón de adaptador permite que esas clases con interfaces incompatibles trabajen juntas, y su alias es un contenedor. El patrón Adapter se puede utilizar como patrón estructural de clase y como patrón estructural de objeto.

El patrón de adaptador consta de cuatro roles:

La clase abstracta de destino define la interfaz específica del dominio que utilizará el cliente;

La clase de adaptador puede llamar a otra interfaz, como convertidor, para adaptar el adaptador y la clase de destino abstracta, que es el núcleo del patrón de adaptador;

La clase de adaptador es el rol a adaptar, que define una interfaz existente, que necesita ser adaptada;

Programe la clase abstracta de destino en la clase de cliente y llame al método comercial definido en la clase abstracta de destino.

En el patrón de adaptador de objetos, la clase de adaptador hereda la clase abstracta de destino (o implementa la interfaz) y define una instancia de objeto de la clase de adaptador, y llama al método comercial correspondiente de la clase de adaptador en el método de clase abstracta de destino heredado.

La principal ventaja del modo de adaptador es desacoplar la clase de destino y la clase de adaptador, lo que aumenta la transparencia y la reutilización de la clase. Al mismo tiempo, la flexibilidad y la escalabilidad del sistema son muy buenas. Es muy conveniente reemplazar el adaptador o agregue un nuevo adaptador. , en línea con "[principio de apertura y cierre] [3]"; la desventaja del patrón de adaptador de clase es que la clase de adaptador no puede adaptarse a múltiples clases de adaptador al mismo tiempo en muchos lenguajes de programación , y la desventaja del patrón de adaptador de objeto es que es difícil reemplazar los Métodos de clase de adaptador.

La aplicación del patrón de adaptador incluye: el sistema necesita usar clases existentes y las interfaces de estas clases no satisfacen las necesidades del sistema; quiere crear una clase reutilizable para usar con algunas clases que no están muy relacionadas entre sí Trabajar.

Supongo que te gusta

Origin blog.csdn.net/zy_dreamer/article/details/132364268
Recomendado
Clasificación