Jugando con patrones de diseño: comprenda las diferencias y aplicaciones de los patrones de diseño creativos en un artículo

Patrón singleton

Punto central: asegúrese de que una clase tenga solo una instancia y proporcione un punto de acceso global.

En el desarrollo real, a menudo nos encontramos con situaciones en las que necesitamos limitar una clase a una sola instancia, como clases de información de configuración, clases de grupo de subprocesos, etc. En este caso, podemos utilizar el patrón singleton. El patrón singleton garantiza que una clase tenga solo una instancia y proporciona un punto de acceso global para que otros objetos puedan obtener instancias de la clase a través de este punto de acceso.

Al implementar el patrón singleton, puede utilizar el enfoque perezoso o hambriento. El estilo perezoso significa que se crea una instancia de la instancia cuando se accede a ella por primera vez, mientras que el estilo hambriento crea la instancia cuando se carga la clase.

Aquí hay un código de ejemplo simple para el patrón singleton:

public class Singleton {
    
    
    private static Singleton instance;

    private Singleton() {
    
    
        // 私有构造方法,防止外部创建实例
    }

    public static Singleton getInstance() {
    
    
        if (instance == null) {
    
    
            // 第一次访问时才进行实例化
            instance = new Singleton();
        }
        return instance;
    }

    // 其他方法...
}

ventaja:

  • Garantiza que solo haya una instancia a nivel global, lo que ahorra recursos del sistema.
  • Proporciona un punto de acceso global para facilitar que otros objetos obtengan instancias.
  • También se garantiza que tendrá solo una instancia en un entorno de subprocesos múltiples.

Comparar con otros modelos similares:

  • El patrón de fábrica simple y el patrón de fábrica también pueden crear objetos, pero se utilizan principalmente para resolver el problema de la creación de objetos, en lugar de garantizar que solo haya una instancia.
  • El patrón de fábrica abstracto puede crear una serie de objetos relacionados, pero su propósito es diferente del patrón singleton: el patrón de fábrica abstracto se preocupa más por la creación de un grupo de objetos, mientras que el patrón singleton solo requiere una instancia.
  • El patrón constructor también puede crear objetos, pero está más preocupado por el proceso de construcción y representación de objetos complejos que por garantizar que solo haya una instancia.

Resumen: el patrón singleton es un patrón de creación de uso común que garantiza que una clase tenga solo una instancia y proporciona un punto de acceso global para obtener fácilmente la instancia. El uso del modo singleton puede ahorrar recursos del sistema, pero debe prestar atención a la seguridad en un entorno de subprocesos múltiples. Al compararlo con otros patrones similares, se pueden comprender mejor las ventajas y los escenarios aplicables del patrón singleton.

Patrón de fábrica

Idea central: definir una interfaz para crear objetos, pero dejar que la subclase decida qué clase crear una instancia.

En la programación orientada a objetos, a menudo nos encontramos con situaciones en las que necesitamos crear múltiples objetos con ciertas características comunes, en este caso podemos usar el patrón de fábrica para gestionar la creación de objetos. El patrón de fábrica define una interfaz para crear objetos, pero la clase específica de objetos que se crearán está determinada por la subclase.

Aquí hay un código de ejemplo para un patrón de fábrica simple:

public interface Product {
    
    
    void show();
}

public class ProductA implements Product {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is product A.");
    }
}

public class ProductB implements Product {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is product B.");
    }
}

public interface Factory {
    
    
    Product createProduct();
}

public class FactoryA implements Factory {
    
    
    @Override
    public Product createProduct() {
    
    
        return new ProductA();
    }
}

public class FactoryB implements Factory {
    
    
    @Override
    public Product createProduct() {
    
    
        return new ProductB();
    }
}

public class Client {
    
    
    public static void main(String[] args) {
    
    
        Factory factory = new FactoryA();
        Product product = factory.createProduct();
        product.show();
    }
}

ventaja:

  • Separe la creación y el uso de objetos, los usuarios solo se preocupan por la interfaz y no necesitan preocuparse por la clase de implementación específica.
  • Cumpliendo con el principio de apertura y cierre, al agregar un producto específico, solo necesita escribir la clase de producto específica correspondiente y la clase de fábrica, y no es necesario modificar otros códigos.

Comparar con otros modelos similares:

  • El patrón de fábrica simple también puede crear objetos, pero coloca la lógica de creación de objetos en una clase de fábrica, violando el principio de apertura y cierre.
  • El patrón singleton garantiza que solo haya una instancia a nivel global y no es adecuado para crear múltiples objetos con las mismas características.
  • El patrón de fábrica abstracto se utiliza para crear una serie de objetos relacionados. La diferencia con el patrón de fábrica es que el patrón de fábrica abstracto se centra más en la creación de un grupo de objetos.

Resumen: el patrón de fábrica es un patrón de creación de uso común: define una interfaz para crear objetos, pero la subclase determina la clase de la que se creará una instancia. El uso del patrón de fábrica puede separar la creación y el uso de objetos, de acuerdo con el principio de apertura y cierre. En comparación con otros patrones similares, el patrón de fábrica presta más atención al proceso de creación de objetos y es adecuado para situaciones en las que es necesario crear múltiples objetos con ciertos puntos en común.

patrón abstracto de fábrica

Idea central: proporcionar una interfaz para crear una serie de objetos relacionados o interdependientes.

El patrón Abstract Factory es un patrón de creación que proporciona una interfaz para crear una serie de objetos relacionados o interdependientes sin especificar una clase específica.

El siguiente es un código de ejemplo simple del patrón de fábrica abstracto:

public interface ProductA {
    
    
    void show();
}

public class ConcreteProductA1 implements ProductA {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product A1.");
    }
}

public class ConcreteProductA2 implements ProductA {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product A2.");
    }
}

public interface ProductB {
    
    
    void show();
}

public class ConcreteProductB1 implements ProductB {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product B1.");
    }
}

public class ConcreteProductB2 implements ProductB {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product B2.");
    }
}

public interface AbstractFactory {
    
    
    ProductA createProductA();
    ProductB createProductB();
}

public class ConcreteFactory1 implements AbstractFactory {
    
    
    @Override
    public ProductA createProductA() {
    
    
        return new ConcreteProductA1();
    }

    @Override
    public ProductB createProductB() {
    
    
        return new ConcreteProductB1();
    }
}

public class ConcreteFactory2 implements AbstractFactory {
    
    
    @Override
    public ProductA createProductA() {
    
    
        return new ConcreteProductA2();
    }

    @Override
    public ProductB createProductB() {
    
    
        return new ConcreteProductB2();
    }
}

public class Client {
    
    
    public static void main(String[] args) {
    
    
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.show();
        productB1.show();

        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.show();
        productB2.show();
    }
}

ventaja:

  • Cree un conjunto de objetos relacionados o interdependientes juntos, diseñados para cumplir con el principio de responsabilidad única.
  • El código del cliente está desacoplado de clases de fábrica específicas, lo que facilita la expansión de nuevas líneas de productos.

Comparar con otros modelos similares:

  • El patrón de fábrica también puede crear objetos, pero se centra en el proceso de creación de objetos de una determinada clase, mientras que el patrón de fábrica abstracto se centra más en la creación de un conjunto de objetos relacionados o interdependientes.
  • El patrón singleton garantiza que solo haya una instancia a nivel global y no es adecuado para crear una serie de objetos.

Resumen: el patrón de fábrica abstracto es un patrón de creación de uso común que proporciona una interfaz para crear una serie de objetos relacionados o interdependientes sin especificar una clase específica. El patrón de fábrica abstracto crea un conjunto de objetos relacionados o interdependientes juntos, logrando el desacoplamiento del cliente de la clase de fábrica específica. En comparación con otros patrones similares, el patrón Abstract Factory se centra más en la creación de un conjunto de objetos.

patrón constructor

Idea central: Separar la construcción de un objeto complejo de su representación, de modo que el mismo proceso de construcción pueda crear diferentes representaciones.

El patrón constructor es un patrón creacional que separa la construcción de un objeto complejo de su representación, permitiendo que el mismo proceso de construcción cree diferentes representaciones.

Aquí hay un código de ejemplo de patrón de construcción simple:

public class Product {
    
    
    private String partA;
    private String partB;

    public void setPartA(String partA) {
    
    
        this.partA = partA;
    }

    public void setPartB(String partB) {
    
    
        this.partB = partB;
    }

    public void show() {
    
    
        System.out.println("Part A: " + partA);
        System.out.println("Part B: " + partB);
    }
}

public abstract class Builder {
    
    
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract Product getResult();
}

public class ConcreteBuilder1 extends Builder {
    
    
    private Product product = new Product();

    @Override
    public void buildPartA() {
    
    
        product.setPartA("Part A from ConcreteBuilder1");
    }

    @Override
    public void buildPartB() {
    
    
        product.setPartB("Part B from ConcreteBuilder1");
    }

    @Override
    public Product getResult() {
    
    
        return product;
    }
}

public class ConcreteBuilder2 extends Builder {
    
    
    private Product product = new Product();

    @Override
    public void buildPartA() {
    
    
        product.setPartA("Part A from ConcreteBuilder2");
    }

    @Override
    public void buildPartB() {
    
    
        product.setPartB("Part B from ConcreteBuilder2");
    }

    @Override
    public Product getResult() {
    
    
        return product;
    }
}

public class Director {
    
    
    public void construct(Builder builder) {
    
    
        builder.buildPartA();
        builder.buildPartB();
    }
}

public class Client {
    
    
    public static void main(String[] args) {
    
    
        Director director = new Director();
        Builder builder1 = new ConcreteBuilder1();
        director.construct(builder1);
        Product product1 = builder1.getResult();
        product1.show();

        Builder builder2 = new ConcreteBuilder2();
        director.construct(builder2);
        Product product2 = builder2.getResult();
        product2.show();
    }
}

ventaja:

  • Separar la construcción de un objeto complejo de su representación hace que el proceso de construcción sea flexible, pudiendo crearse diferentes representaciones para un mismo proceso de construcción.
  • El cliente no necesita conocer el proceso de construcción específico, solo necesita especificar el objeto de construcción específico, lo que simplifica el uso del cliente.

Comparar con otros modelos similares:

  • El patrón de fábrica también se utiliza para crear objetos, pero se centra más en el proceso de creación de objetos, mientras que el patrón de construcción se centra más en el proceso de construcción y representación de objetos.
  • El patrón Abstract Factory también puede crear una serie de objetos relacionados, lo que crea un grupo de objetos relacionados juntos, mientras que el patrón Builder separa la construcción de un objeto complejo de su representación.

Resumen: El patrón constructor es un patrón de creación comúnmente utilizado que separa la construcción de un objeto complejo de su representación, haciendo que el proceso de construcción sea flexible y capaz de crear diferentes representaciones de un mismo proceso de construcción. El uso del patrón de creación puede resolver mejor el problema de crear objetos complejos y, al mismo tiempo, hacer que el código del cliente sea más conciso y más fácil de mantener. En comparación con otros patrones similares, el patrón constructor se centra más en el proceso de construcción y representación de objetos.

Patrón de prototipo

Descripción general
El patrón prototipo es un patrón de creación que crea nuevos objetos copiando objetos existentes, evitando procesos de inicialización repetidos. La idea central es copiar objetos existentes mediante el método de clonación para crear nuevos objetos. El patrón prototipo es adecuado para situaciones en las que es necesario crear una gran cantidad de objetos similares, pero el proceso de creación de objetos lleva mucho tiempo o es costoso.

Ejemplo de código
A continuación se muestra un ejemplo de código que utiliza el patrón prototipo:

// 原型接口
interface Prototype {
    
    
    Prototype clone();  // 克隆方法
}

// 具体原型类
class ConcretePrototype implements Prototype {
    
    
    private String name;

    public ConcretePrototype(String name) {
    
    
        this.name = name;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototype(this.name);
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return this.name;
    }
}

// 客户端代码
public class Client {
    
    
    public static void main(String[] args) {
    
    
        ConcretePrototype prototype = new ConcretePrototype("原型对象");
        ConcretePrototype clone = (ConcretePrototype) prototype.clone();
        clone.setName("克隆对象");

        System.out.println(prototype.getName());  // 输出:原型对象
        System.out.println(clone.getName());      // 输出:克隆对象
    }
}

En el ejemplo anterior, definimos una interfaz prototipo Prototypeque contiene un método de clonación clone(). La clase prototipo específica ConcretePrototypeimplementa la interfaz prototipo e implementa el método de clonación, en el que se crea y devuelve un nuevo objeto. El código del cliente utiliza el patrón prototipo para crear un objeto prototipo y obtiene un objeto clonado a través del método clonar.

Análisis de ventajas y desventajas
Las ventajas del modo prototipo son las siguientes:

  • Ahorre tiempo y recursos de inicialización de objetos. Dado que el modo prototipo crea nuevos objetos clonando objetos existentes, evita procesos de inicialización repetidos y mejora la eficiencia de la creación de objetos.
  • Simplifique el proceso de creación de objetos. A través del modo prototipo, podemos copiar directamente el estado de un objeto existente sin establecer manualmente el valor de cada propiedad, lo que simplifica el proceso de creación del objeto.

Las desventajas del patrón prototipo son las siguientes:

  • La clonación de objetos puede estar restringida. La clonación de algunos objetos está restringida, por ejemplo, los objetos singleton no se pueden clonar, los objetos no serializables no se pueden clonar, etc.
  • La clonación de objetos puede causar problemas de copia profunda. Si las propiedades del objeto contienen variables miembro de tipo de referencia, pueden ocurrir problemas de copia profunda durante la clonación y debe prestar atención a esto.

Comparación con otros modos.

  • Patrón prototipo y patrón fábrica: El patrón prototipo y el patrón fábrica son ambos patrones creacionales, pero sus propósitos son diferentes. El patrón prototipo se centra en cómo crear nuevos objetos copiando objetos existentes, mientras que el patrón de fábrica se centra en cómo crear objetos mediante métodos o clases de fábrica.
  • Patrón prototipo y patrón singleton: El patrón prototipo y el patrón singleton son patrones creacionales, pero sus propósitos son completamente diferentes. El patrón prototipo tiene como objetivo crear nuevos objetos, cada uno de los cuales tiene un estado independiente, mientras que el patrón singleton tiene como objetivo crear objetos únicos, todos los cuales comparten el mismo estado.

En resumen, el patrón prototipo es un patrón de creación que crea nuevos objetos copiando objetos existentes y es adecuado para situaciones en las que es necesario crear una gran cantidad de objetos similares. Puede mejorar la eficiencia de la creación de objetos y simplificar el proceso de creación de objetos. Sin embargo, es necesario prestar atención a las limitaciones de la clonación de objetos y a los problemas de copia profunda.

En general, el patrón prototipo es un patrón de diseño simple y práctico que puede mejorar efectivamente la reutilización y la eficiencia de la creación del código y es adecuado para varios escenarios de aplicaciones.

Supongo que te gusta

Origin blog.csdn.net/jingyoushui/article/details/132953522
Recomendado
Clasificación