Patrón de diseño-01 Patrón de fábrica simple Explicación detallada Comparación detallada de códigos


Este artículo presentará qué es el patrón de fábrica simple y por qué deberíamos usar este patrón. En comparación con el código nativo, se explica cómo reduce el acoplamiento del código, así como la comparación detallada del código, combinado con las preguntas y respuestas de ChatGPT. También es un registro de mi propio aprendizaje. Corríjame si me equivoco.

Preguntas y respuestas de ChatGpt

P: Dé un ejemplo para ilustrar los beneficios de reducir el acoplamiento
del modelo de fábrica simple en Java, que se refleja mejor en el código.

Dé un ejemplo para ilustrar los beneficios de reducir el acoplamiento mediante el patrón de fábrica simple en Java, que se refleja mejor en el código.

¡Ciertamente! Ilustremos los beneficios de reducir el acoplamiento utilizando un modelo de fábrica simple en Java. Comenzaremos con una implementación acoplada y luego la refactorizaremos para reducir el acoplamiento.

¡ciertamente! Ilustremos los beneficios de utilizar un modelo de fábrica simple en Java para reducir el acoplamiento. Comenzaremos con una implementación acoplada y luego la refactorizaremos para reducir el acoplamiento.

Implementación acoplada (alto acoplamiento):

Considere una fábrica simple que produce diferentes tipos de vehículos (por ejemplo, automóviles y bicicletas) según un tipo proporcionado. En este ejemplo acoplado, el método de fábrica tiene un alto nivel de acoplamiento con las clases de vehículos concretas.

Considere una fábrica sencilla que produce diferentes tipos de vehículos (por ejemplo, automóviles y bicicletas) según el tipo proporcionado. En este ejemplo de acoplamiento, el método de fábrica está altamente acoplado a la clase de vehículo concreta.

código nativo

class VehicleFactory {
    
    
    public Vehicle createVehicle(String type) {
    
    
        if ("car".equalsIgnoreCase(type)) {
    
    
            return new Car();
        } else if ("bicycle".equalsIgnoreCase(type)) {
    
    
            return new Bicycle();
        } else {
    
    
            throw new IllegalArgumentException("Invalid vehicle type");
        }
    }
}

class Car {
    
    
    void start() {
    
    
        System.out.println("Car started.");
    }
}

class Bicycle {
    
    
    void start() {
    
    
        System.out.println("Bicycle started.");
    }
}

public class Main {
    
    
    public static void main(String[] args) {
    
    
        VehicleFactory factory = new VehicleFactory();
        
        Vehicle vehicle1 = factory.createVehicle("car");
        vehicle1.start(); // Output: Car started.
        
        Vehicle vehicle2 = factory.createVehicle("bicycle");
        vehicle2.start(); // Output: Bicycle started.
    }
}

En este ejemplo, la VehicleFactoryclase tiene un alto acoplamiento porque crea directamente instancias de Cary Bicycle. Si necesitamos agregar más tipos de vehículos en el futuro, necesitaríamos modificar el método de fábrica, lo que resultaría en un mayor acoplamiento y una menor flexibilidad.

En este ejemplo, VehicleFactoryla clase está altamente acoplada porque crea directamente instancias de Cary Bicycle. Si necesita agregar más tipos de vehículos en el futuro, deberá modificar el método de fábrica, lo que dará como resultado un mayor acoplamiento y una menor flexibilidad.

Código de patrón de fábrica simple

Implementación de acoplamiento reducido (acoplamiento bajo):

Para reducir el acoplamiento, podemos usar interfaces y clases abstractas para definir un contrato común para todos los vehículos. De esta forma, el método de fábrica no necesita conocer las clases concretas de vehículos.

interface Vehicle {
    
    
    void start();
}

class Car implements Vehicle {
    
    
    public void start() {
    
    
        System.out.println("Car started.");
    }
}

class Bicycle implements Vehicle {
    
    
    public void start() {
    
    
        System.out.println("Bicycle started.");
    }
}

class VehicleFactory {
    
    
    public Vehicle createVehicle(String type) {
    
    
        if ("car".equalsIgnoreCase(type)) {
    
    
            return new Car();
        } else if ("bicycle".equalsIgnoreCase(type)) {
    
    
            return new Bicycle();
        } else {
    
    
            throw new IllegalArgumentException("Invalid vehicle type");
        }
    }
}

public class Main {
    
    
    public static void main(String[] args) {
    
    
        VehicleFactory factory = new VehicleFactory();
        
        Vehicle vehicle1 = factory.createVehicle("car");
        vehicle1.start(); // Output: Car started.
        
        Vehicle vehicle2 = factory.createVehicle("bicycle");
        vehicle2.start(); // Output: Bicycle started.
    }
}

En este ejemplo refactorizado, hemos introducido un interface Vehicle, que implementa Carambos Bicycle. Ahora VehicleFactorydevuelve instancias de la Vehicleinterfaz en lugar de clases concretas. Esto reduce el acoplamiento porque el método de fábrica no depende de implementaciones específicas, lo que facilita ampliar el sistema con nuevos tipos de vehículos sin modificar el código existente.

En este ejemplo refactorizado, introdujimos una interfaz "Vehículo", que tanto "Car" como "Bicycle" implementan. "VehicleFactory" ahora devuelve una instancia de la interfaz "Vehicle" en lugar de una clase concreta. Esto reduce el acoplamiento porque los métodos de fábrica no están vinculados a una implementación específica, lo que facilita ampliar el sistema con nuevos tipos de vehículos sin modificar el código existente.

Patrón de fábrica simple

Es un patrón de diseño creacional que proporciona una manera fácil de crear objetos sin exponer directamente la lógica de creación de objetos al cliente.

El patrón de fábrica simple también se denomina patrón de método de fábrica estático. Su propósito es simple: definir una interfaz para la creación de objetos.
Estructura de composición:

  1. Rol de fábrica (Creador): este es el núcleo de este modelo y contiene cierta lógica empresarial y lógica de juicio. En Java, a menudo se implementa mediante una clase concreta.

  2. Rol de producto abstracto (Producto): generalmente es la clase principal heredada por un producto específico o la interfaz implementada. Se implementa en java mediante interfaz o clase abstracta.

  3. Rol de producto concreto (ConcreteProduct): el objeto creado por la clase de fábrica es una instancia de este rol. Implementado por una clase concreta en java.

Utilice un diagrama de clases para representar la relación entre ellos.
Insertar descripción de la imagen aquí
Rol de producto abstracto: Vehículo.
Rol de producto específico: Automóvil, Bicicleta.
Rol de clase de fábrica: VehicleFactory.

Añade un nuevo barco para comparar los dos métodos.

código nativo

¡Ciertamente! En un enfoque de alto acoplamiento, se crearían directamente instancias de clases de vehículos dentro del método de fábrica, lo que puede generar estrechas dependencias entre las clases de vehículos de fábrica y concretas. A continuación se muestra un ejemplo de un enfoque de alto acoplamiento:

¡ciertamente! En un enfoque de alto acoplamiento, creará una instancia de la clase de vehículo directamente en el método de fábrica, lo que puede resultar en una estrecha dependencia entre la clase de vehículo de fábrica y concreta. A continuación se muestra un ejemplo de un enfoque altamente acoplado:

class Car {
    
    
    void start() {
    
    
        System.out.println("Car started.");
    }
}

class Bicycle {
    
    
    void start() {
    
    
        System.out.println("Bicycle started.");
    }
}

class Boat {
    
    
    void start() {
    
    
        System.out.println("Boat started.");
    }
}

class VehicleFactory {
    
    
    public Object createVehicle(String type) {
    
    
        if ("car".equalsIgnoreCase(type)) {
    
    
            return new Car();
        } else if ("bicycle".equalsIgnoreCase(type)) {
    
    
            return new Bicycle();
        } else if ("boat".equalsIgnoreCase(type)) {
    
    
            return new Boat();
        } else {
    
    
            throw new IllegalArgumentException("Invalid vehicle type");
        }
    }
}

public class Main {
    
    
    public static void main(String[] args) {
    
    
        VehicleFactory factory = new VehicleFactory();

        Car car = (Car) factory.createVehicle("car");
        car.start(); // Output: Car started.

        Bicycle bicycle = (Bicycle) factory.createVehicle("bicycle");
        bicycle.start(); // Output: Bicycle started.

        Boat boat = (Boat) factory.createVehicle("boat");
        boat.start(); // Output: Boat started.
    }
}

En este enfoque de alto acoplamiento:

  1. Cada clase de vehículo ( Car,, ) se instancia directamente dentro del Bicyclemétodo de .BoatcreateVehicleVehicleFactory
  2. Para usar un vehículo específico, debes convertir el objeto devuelto por la fábrica a la clase de vehículo correspondiente ( Car, Bicycle, Boat).
  3. Agregar un nuevo tipo de vehículo requeriría modificarlo VehicleFactorypara crear ese tipo de vehículo directamente.

En este enfoque altamente acoplado:

  1. Cada clase de vehículo ("Coche", "Bicicleta", "Barco") se crea una instancia directamente en el método "createVehicle" de "VehicleFactory".
  2. Para utilizar un vehículo específico, el objeto devuelto por la fábrica debe convertirse a la clase de vehículo correspondiente ( Car, Bicycle, Boat).
  3. Agregar un nuevo tipo de vehículo requiere una modificación VehicleFactorypara crear ese tipo de vehículo directamente.

Un alto acoplamiento puede hacer que el código sea menos flexible y más difícil de mantener porque cualquier cambio en el método de fábrica o en las clases de vehículos concretas puede afectar otras partes del código que dependen de ellos. Generalmente, es una buena práctica reducir el acoplamiento y utilizar interfaces o clases abstractas para lograr una mayor flexibilidad y mantenibilidad.

Un alto acoplamiento puede hacer que el código sea menos flexible y difícil de mantener, ya que cualquier cambio en los métodos de fábrica o en las clases concretas de vehículos puede afectar otras partes del código que dependen de ellos. Generalmente, la mejor práctica es reducir el acoplamiento y utilizar interfaces o clases abstractas para una mayor flexibilidad y mantenibilidad.

¿Por qué utilizar yeso?

Coche coche = (Coche) factory.createVehicle(“coche”)

En el enfoque de alto acoplamiento que proporcioné anteriormente, tiene razón en que se requiere conversión de tipos cuando recupera los objetos creados de la fábrica. Esta es una limitación del alto acoplamiento porque estás creando directamente instancias de clases específicas dentro del método de fábrica. Déjame explicarte esto con más detalle:

En el método createVehicle de VehicleFactory, la fábrica crea instancias de Car, Bicycle o Boat según el parámetro de tipo.

Dado que el método createVehicle está declarado para devolver un Objeto, cuando recupera el objeto creado, se trata como una referencia de Objeto.

Para utilizar la funcionalidad específica de un Car, por ejemplo, debe volver a convertir la referencia del Objeto a Car para acceder a métodos específicos de Car, como el inicio.

Esta conversión de tipo presenta problemas potenciales porque si proporciona el tipo incorrecto para el parámetro de tipo o si introduce un nuevo tipo de vehículo en el futuro, puede obtener errores de tiempo de ejecución (ClassCastException) si la conversión no coincide con el tipo real.

Por el contrario, un enfoque de bajo acoplamiento, como se demostró en el ejemplo anterior, utiliza interfaces o clases abstractas para crear un contrato común para todos los vehículos. De esta manera, puede evitar la conversión de tipos y manejar todos los vehículos de manera uniforme confiando en la interfaz común. Proporciona una mayor flexibilidad, mantenibilidad y seguridad de tipos, ya que no es necesario convertir objetos a tipos específicos cuando los usa.

En el enfoque de alto acoplamiento que proporcioné anteriormente, tiene razón en que se requiere conversión de tipos cuando recupera el objeto creado de la fábrica. Esta es una limitación del alto acoplamiento porque estás creando instancias de una clase específica directamente en el método de fábrica. Déjame explicarlo con más detalle:

En el método createVehicle de VehicleFactory, la fábrica crea una instancia de Car, Bicycle o Boat según el parámetro de tipo.

Debido a que el método createVehicle está declarado para devolver un objeto, cuando recupera el objeto creado, se trata como una referencia de objeto.

Por ejemplo, para utilizar la funcionalidad específica de un automóvil, debe devolver la referencia del objeto al automóvil para acceder a los métodos específicos del automóvil, como el inicio.

Esta conversión de tipo crea problemas potenciales porque si proporciona el tipo incorrecto para el parámetro de tipo, o si introduce un nuevo tipo de vehículo en el futuro y la conversión no coincide con el tipo real, puede obtener un error de tiempo de ejecución (ClassCastException).

Por el contrario, un enfoque de bajo acoplamiento (como se muestra en el ejemplo anterior) utiliza interfaces o clases abstractas para crear un contrato común para todos los vehículos. De esta manera, evita conversiones de tipos y confía en una interfaz común para manejar todos los vehículos de manera uniforme. Proporciona mayor flexibilidad, mantenibilidad y seguridad de tipos porque no es necesario convertir el objeto a un tipo específico cuando lo usa.

Patrón de fábrica simple

P: muéstrame el método de acoplamiento alto

¡Ciertamente! Agreguemos un nuevo Boatvehículo al código existente. Seguiremos el mismo enfoque de usar una interfaz Boaty actualizar el método de fábrica para crear Boatinstancias sin modificar el código existente.

¡ciertamente! Agreguemos un nuevo vehículo "Barco" a nuestro código existente. Seguiremos el mismo enfoque, utilizando la interfaz "Boat" y actualizando el método de fábrica para crear instancias "Boat" sin modificar el código existente.

Agregar un vehículo tipo barco (acoplamiento bajo):

interface Vehicle {
    
    
    void start();
}

class Car implements Vehicle {
    
    
    public void start() {
    
    
        System.out.println("Car started.");
    }
}

class Bicycle implements Vehicle {
    
    
    public void start() {
    
    
        System.out.println("Bicycle started.");
    }
}

class Boat implements Vehicle {
    
    
    public void start() {
    
    
        System.out.println("Boat started.");
    }
}

class VehicleFactory {
    
    
    public Vehicle createVehicle(String type) {
    
    
        if ("car".equalsIgnoreCase(type)) {
    
    
            return new Car();
        } else if ("bicycle".equalsIgnoreCase(type)) {
    
    
            return new Bicycle();
        } else if ("boat".equalsIgnoreCase(type)) {
    
    
            return new Boat();
        } else {
    
    
            throw new IllegalArgumentException("Invalid vehicle type");
        }
    }
}

public class Main {
    
    
    public static void main(String[] args) {
    
    
        VehicleFactory factory = new VehicleFactory();

        Vehicle vehicle1 = factory.createVehicle("car");
        vehicle1.start(); // Output: Car started.

        Vehicle vehicle2 = factory.createVehicle("bicycle");
        vehicle2.start(); // Output: Bicycle started.

        Vehicle vehicle3 = factory.createVehicle("boat");
        vehicle3.start(); // Output: Boat started.
    }
}

En este código actualizado, hemos introducido una nueva Boatclase que implementa la Vehicleinterfaz. Se VehicleFactoryha actualizado para manejar la creación de Boatinstancias cuando se pasa "barco" como tipo. Esto nos permite agregar un nuevo tipo de vehículo (en este caso, un barco) sin modificar el código existente de fábrica o de los demás vehículos. Esto demuestra la flexibilidad y el bajo acoplamiento logrado mediante el uso de interfaces y un enfoque de fábrica abstracto.

En este código actualizado, hemos introducido una nueva clase "Barco" que implementa la interfaz "Vehículo". 'VehicleFactory' se ha actualizado para manejar la creación de instancias de 'Boat' cuando se pasa 'boat' como tipo. Esto nos permite añadir un nuevo tipo de vehículo (en este caso, una embarcación) sin modificar el código existente de fábrica u otros vehículos. Esto demuestra la flexibilidad y el bajo acoplamiento logrado mediante el uso de interfaces y métodos de fábrica abstractos.

Resumen del método de fábrica simple

Diferencias con el código nativo:

Explique desde tres dimensiones:
Rol del producto abstracto – Vehículo
Rol del producto específico del vehículo – Automóvil,
Fábrica de bicicletas Rol de clase – Fábrica de vehículos

1 El rol de producto abstracto Vehículo en el patrón de fábrica simple usa una interfaz y el código nativo es una clase
2 El rol de producto específico Car en el patrón de fábrica simple necesita implementar la interfaz y el código nativo es una clase separada
3 La clase de fábrica específica rol en el patrón de fábrica simple: VehicleFactory El objeto de retorno es Interfaz de vehículo, el objeto de retorno del código nativo es Objeto

ventaja:

  • Concentrar la lógica de creación de objetos en la clase de fábrica reduce la complejidad del cliente.
  • Los detalles de la creación del objeto están ocultos y el cliente solo debe preocuparse por qué tipo de objeto debe crearse, no cómo se crea.
    Se pueden agregar fácilmente nuevas clases de productos modificando la clase de fábrica

defecto:

  • Si hay demasiadas clases de productos, el código de la clase de fábrica será muy complicado y difícil de mantener.
  • Al agregar un nuevo producto, es necesario modificar la clase de fábrica, es decir, se agregará una nueva declaración de caso a la clase OperationFactory, lo que viola el principio de apertura y cierre.

En términos generales, el patrón de fábrica simple es adecuado para escenarios donde la lógica de creación de objetos es relativamente simple y el número de clases de productos es pequeño. Para la creación de objetos más complejos y las dependencias entre objetos, considere usar otros patrones de diseño de creación, como el patrón Factory Method o el patrón Abstract Factory.

referencia

1 Patrón de diseño 01. Método de fábrica simple https://juejin.cn/post/7267091509953855543

2 Patrón de diseño JAVA (3) – Patrón de fábrica
https://juejin.cn/post/7257441765976162361?searchId=202309061335355A323BC0D43AD67B950D#heading-0

Supongo que te gusta

Origin blog.csdn.net/qq_41398619/article/details/132713524
Recomendado
Clasificación