¡Se pueden hacer 23 patrones de diseño comunes y siete principios de patrones de diseño en un artículo!

En el desarrollo de software, los patrones de diseño son una solución comprobada que ayuda a los desarrolladores a organizar y escribir mejor el código. Los patrones de diseño no solo pueden mejorar la legibilidad y el mantenimiento del código, sino también acelerar el proceso de desarrollo de software.

Este artículo presentará 23 patrones de diseño comunes y siete principios de patrones de diseño, y brindará explicaciones detalladas y demostraciones de código de muestra para cada patrón.

23 patrones de diseño

Patrones creacionales

Los patrones de creación se centran en el proceso de creación de objetos, incluidos los patrones de fábrica simples, los patrones de método de fábrica, los patrones de fábrica abstractos, los patrones de singleton, los patrones de construcción y los patrones de prototipo.

  1. Patrón de fábrica simple

El patrón de fábrica simple crea objetos a través de una clase de fábrica, oculta los detalles de la creación de objetos y proporciona una interfaz unificada, de modo que el cliente no necesita conocer la implementación específica.

public class SimpleFactory {
    
    
    public static Product createProduct(String type) {
    
    
        if (type.equals("A")) {
    
    
            return new ConcreteProductA();
        } else if (type.equals("B")) {
    
    
            return new ConcreteProductB();
        } else {
    
    
            throw new IllegalArgumentException("Invalid product type: " + type);
        }
    }
}
  1. patrón de método de fábrica

El patrón del método de fábrica difiere la creación de objetos a las subclases, desacoplando al permitir que las subclases decidan cómo crear objetos.

public abstract class Creator {
    
    
    public abstract Product createProduct();
}

public class ConcreteCreatorA extends Creator {
    
    
    public Product createProduct() {
    
    
        return new ConcreteProductA();
    }
}

public class ConcreteCreatorB extends Creator {
    
    
    public Product createProduct() {
    
    
        return new ConcreteProductB();
    }
}
  1. patrón de fábrica abstracto

El patrón de fábrica abstracto proporciona una interfaz para crear una serie de productos relacionados sin especificar una clase de implementación específica. Extiende el patrón del método de fábrica a varias familias de productos.

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

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

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

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

    public ProductB createProductB() {
    
    
        return new ConcreteProductB2();
    }
}
  1. patrón único

El patrón singleton garantiza que solo hay una instancia de una clase y proporciona un punto de acceso global para que otros objetos puedan acceder a la instancia.

public class Singleton {
    
    
    private static Singleton instance;

    private Singleton() {
    
    }

    public static synchronized Singleton getInstance() {
    
    
        if (instance == null) {
    
    
            instance = new Singleton();
        }
        return instance;
    }
}
  1. modo constructor

El patrón de constructor divide el proceso de creación de un objeto complejo en varios pasos simples, y diferentes constructores pueden usar estos pasos para construir diferentes objetos.

public class Product {
    
    
    private String part1;
    private String part2;

    public void setPart1(String part1) {
    
    
        this.part1 = part1;
    }

    public void setPart2(String part2) {
    
    
        this.part2 = part2;
    }
}

public abstract class AbstractBuilder {
    
    
    protected Product product = new Product();

    public abstract void buildPart1();
    public abstract void buildPart2();

    public Product getResult() {
    
    
        return product;
    }
}

public class ConcreteBuilder extends AbstractBuilder {
    
    
    public void buildPart1() {
    
    
        product.setPart1("Part 1");
    }

    public void buildPart2() {
    
    
        product.setPart2("Part 2");
    }
}

public class Director {
    
    
    private AbstractBuilder builder;

    public Director(AbstractBuilder builder) {
    
    
        this.builder = builder;
    }

    public void buildProduct() {
    
    
        builder.buildPart1();
        builder.buildPart2();
    }
}
  1. patrón de prototipo

El modo prototipo crea nuevos objetos especificando un objeto prototipo y se pueden crear nuevos objetos mediante la clonación.

public abstract class Prototype implements Cloneable {
    
    
    public abstract Prototype clone();
}

public class ConcretePrototypeA extends Prototype {
    
    
    public Prototype clone() {
    
    
        try {
    
    
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
    
    
            return null;
        }
    }
}

public class Client {
    
    
    private Prototype prototype;

    public Client(public Prototype prototype) {
    
    
        this.prototype = prototype;
    }

    public Prototype createPrototype() {
    
    
        return prototype.clone();
    }
}

patrón estructural

Los patrones estructurales se centran en cómo se combinan los objetos, incluidos los patrones de adaptador, los patrones de puente, los patrones de composición, los patrones de decorador, los patrones de apariencia, los patrones de peso ligero y los patrones de proxy.

  1. patrón de adaptador

El patrón de adaptador convierte la interfaz de una clase en otra interfaz esperada por los clientes. Implementa la conversión de interfaz encapsulando una clase existente.

public interface Target {
    
    
    void request();
}

public class Adaptee {
    
    
    public void specificRequest() {
    
    }
}

public class Adapter implements Target {
    
    
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
    
    
        this.adaptee = adaptee;
    }

    public void request() {
    
    
        adaptee.specificRequest();
    }
}
  1. Modo Puente

El patrón de puente separa la abstracción de la implementación para que puedan variar de forma independiente. Lo hace delegando detalles de implementación a otra clase.

public abstract class Abstraction {
    
    
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
    
    
        this.implementor = implementor;
    }

    public abstract void operation();
}

public interface Implementor {
    
    
    void operationImpl();
}

public class ConcreteImplementorA implements Implementor {
    
    
    public void operationImpl() {
    
    }
}

public class RefinedAbstraction extends Abstraction {
    
    
    public RefinedAbstraction(Implementor implementor) {
    
    
        super(implementor);
    }

    public void operation() {
    
    
        implementor.operationImpl();
    }
}
  1. modo de combinación

El patrón compuesto organiza un conjunto de objetos en una estructura de árbol para representar una jerarquía de "parte-todo". Permite a los clientes trabajar uniformemente con objetos únicos y compuestos.

public abstract class Component {
    
    
    protected String name;

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

    public abstract void add(Component component);
    public abstract void remove(Component component);
    public abstract void display(int depth);
}

public class Leaf extends Component {
    
    
    public Leaf(String name) {
    
    
        super(name);
    }

    public void add(Component component) {
    
    }
    public void remove(Component component) {
    
    }

    public void display(int depth) {
    
    
        System.out.println("-".repeat(depth) + name);
    }
}

public class Composite extends Component {
    
    
    private List<Component> children = new ArrayList<>();

    public Composite(String name) {
    
    
        super(name);
    }

    public void add(Component component) {
    
    
        children.add(component);
    }

    public void remove(Component component) {
    
    
        children.remove(component);
    }

    public void display(int depth) {
    
    
        System.out.println("-".repeat(depth) + name);
        for (Component component : children) {
    
    
            component.display(depth + 1);
        }
    }
}
  1. patrón decorador

El patrón decorador puede extender su funcionalidad envolviendo un objeto decorador sin cambiar el objeto original.

public abstract class Component {
    
    
    public abstract void operation();
}

public class ConcreteComponent extends Component {
    
    
    public void operation() {
    
    }
}

public abstract class Decorator extends Component {
    
    
    protected Component component;

    public Decorator(Component component) {
    
    
        this.component = component;
    }

    public void operation() {
    
    
        component.operation();
    }
}

public class ConcreteDecoratorA extends Decorator {
    
    
    public ConcreteDecoratorA(Component component) {
    
    
        super(component);
    }

    public void operation() {
    
    
        super.operation();
        // Add extra behavior
    }
}
  1. modo de apariencia

El patrón de fachada proporciona una interfaz simple que oculta la compleja estructura interna de un conjunto de subsistemas. Desacopla las dependencias entre clientes y subsistemas.

public class Subsystem1 {
    
    
    public void operation1() {
    
    }
}

public class Subsystem2 {
    
    
    public void operation2() {
    
    }
}

public class Facade {
    
    
    private Subsystem1 subsystem1;
    private Subsystem2 subsystem2;

    public Facade() {
    
    
        subsystem1 = new Subsystem1();
        subsystem2 = new Subsystem2();
    }

    public void operation() {
    
    
        subsystem1.operation1();
        subsystem2.operation2();
    }
}
  1. Modo de peso mosca

El modo Flyweight reduce la cantidad de objetos en la memoria al compartir objetos, lo que mejora el rendimiento del sistema. Divide los objetos en estado interno y estado externo, el estado interno se puede compartir y el cliente debe pasar el estado externo.

public interface Flyweight {
    
    
    void operation(String extrinsicState);
}

public class ConcreteFlyweight implements Flyweight {
    
    
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
    
    
        this.intrinsicState = intrinsicState;
    }

    public void operation(String extrinsicState) {
    
    }
}

public class FlyweightFactory {
    
    
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
    
    
        if (!flyweights.containsKey(key)) {
    
    
            flyweights.put(key, new ConcreteFlyweight(key));
        }
        return flyweights.get(key);
    }
}
  1. modo proxy

El modo proxy introduce un objeto proxy al acceder a un objeto para controlar el acceso al objeto original. Puede ocultar los detalles de implementación del objeto y proporcionar una forma de acceder al objeto de forma segura.

public interface Subject {
    
    
    void request();
}

public class RealSubject implements Subject {
    
    
    public void request() {
    
    }
}

public class Proxy implements Subject {
    
    
    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
    
    
        this.realSubject = realSubject;
    }

    public void request() {
    
    
        // Access control and additional behavior
        realSubject.request();
        // Additional behavior
    }
}

Siete principios de patrones de diseño

  1. Principio de responsabilidad única (PRS)

Una clase debe tener una sola razón para cambiarla.

  1. Principio Abierto Cerrado (OCP)

Las entidades de software deben estar abiertas para la extensión y cerradas para la modificación.

  1. Principio de sustitución de Liskov (LSP)

Un subtipo debe poder reemplazar completamente a su supertipo.

  1. Principio de segregación de interfaz (ISP)

Un cliente no debe depender de interfaces que no necesita.

  1. Principio de inversión de dependencia (DIP)

Los módulos de alto nivel no deberían depender de los módulos de bajo nivel, deberían depender de interfaces abstractas. Las interfaces abstractas no deberían depender de implementaciones concretas, y las implementaciones concretas deberían depender de interfaces abstractas.

  1. Ley de Deméter (LoD)

Un objeto debe tener un conocimiento mínimo sobre otros objetos.

  1. Principio de reutilización de combinación/agregación (CARP)

Al combinar un grupo de objetos en un nuevo objeto, debe usar combinación/agregación en lugar de herencia para lograr el propósito de reutilización.

Resumir

Los patrones de diseño y los principios de diseño son conceptos muy importantes en el desarrollo de software, pueden ayudarnos a comprender y diseñar mejor los sistemas de software. Este artículo presenta 23 patrones de diseño comunes y siete principios de patrones de diseño, y proporciona demostraciones detalladas de código de muestra. Espero que los lectores puedan dominar este conocimiento a través de este artículo y aplicarlo en el desarrollo real.

Supongo que te gusta

Origin blog.csdn.net/weixin_43025343/article/details/131865131
Recomendado
Clasificación