23 modèles de conception courants et sept principes de modèles de conception peuvent être rédigés dans un seul article !

Dans le développement de logiciels, les modèles de conception sont une solution éprouvée qui aide les développeurs à mieux organiser et écrire du code. Les modèles de conception peuvent non seulement améliorer la lisibilité et la maintenabilité du code, mais aussi accélérer le processus de développement logiciel.

Cet article présentera 23 modèles de conception courants et sept principes de modèle de conception, et donnera des explications détaillées et des exemples de démonstration de code pour chaque modèle.

23 modèles de conception

Modèles de création

Les modèles de création se concentrent sur le processus de création d'objets, y compris les modèles d'usine simples, les modèles de méthode d'usine, les modèles d'usine abstraits, les modèles singleton, les modèles de générateur et les modèles de prototype.

  1. Modèle d'usine simple

Le modèle de fabrique simple crée des objets via une classe de fabrique, masque les détails de la création d'objets et fournit une interface unifiée, de sorte que le client n'a pas besoin de connaître l'implémentation spécifique.

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. modèle de méthode d'usine

Le modèle de méthode d'usine reporte la création d'objets aux sous-classes, se découplant en laissant les sous-classes décider comment créer des objets.

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. modèle d'usine abstrait

Le modèle de fabrique abstraite fournit une interface pour créer une série de produits associés sans spécifier de classe d'implémentation spécifique. Il étend le modèle de méthode d'usine à plusieurs familles de produits.

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. motif singleton

Le modèle singleton garantit qu'il n'y a qu'une seule instance d'une classe et fournit un point d'accès global afin que d'autres objets puissent accéder à l'instance.

public class Singleton {
    
    
    private static Singleton instance;

    private Singleton() {
    
    }

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

Le modèle de générateur divise le processus de création d'un objet complexe en plusieurs étapes simples, et différents générateurs peuvent utiliser ces étapes pour créer différents objets.

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. modèle de prototype

Le mode prototype crée de nouveaux objets en spécifiant un objet prototype, et de nouveaux objets peuvent être créés par clonage.

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();
    }
}

modèle structurel

Les modèles structurels se concentrent sur la façon dont les objets sont combinés, y compris les modèles d'adaptateur, les modèles de pont, les modèles de composition, les modèles de décorateur, les modèles d'apparence, les modèles de poids mouche et les modèles de proxy.

  1. modèle d'adaptateur

Le modèle d'adaptateur convertit l'interface d'une classe en une autre interface attendue par les clients. Il implémente la conversion d'interface en encapsulant une classe existante.

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. mode pont

Le modèle de pont sépare l'abstraction de l'implémentation afin qu'elles puissent varier indépendamment. Pour ce faire, il délègue les détails d'implémentation à une autre classe.

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. mode combiné

Le modèle Composite organise un ensemble d'objets dans une structure arborescente pour représenter une hiérarchie "partie-tout". Il permet aux clients de travailler uniformément avec des objets simples et composites.

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. motif décorateur

Le motif décorateur peut étendre ses fonctionnalités en enveloppant un objet décorateur sans modifier l'objet d'origine.

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. mode d'apparence

Le motif de façade fournit une interface simple qui masque la structure interne complexe d'un ensemble de sous-systèmes. Il dissocie les dépendances entre les clients et les sous-systèmes.

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. Mode poids mouche

Le mode poids plume réduit le nombre d'objets en mémoire en partageant des objets, améliorant ainsi les performances du système. Il divise les objets en état interne et état externe, l'état interne peut être partagé et l'état externe doit être transmis par le client.

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. Mode proxy

Le mode proxy introduit un objet proxy lors de l'accès à un objet pour contrôler l'accès à l'objet d'origine. Il peut masquer les détails d'implémentation de l'objet et fournir un moyen d'accéder à l'objet en toute sécurité.

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
    }
}

Sept principes de modèle de conception

  1. Principe de responsabilité unique (SRP)

Une classe ne devrait avoir qu'une seule raison de la changer.

  1. Principe Ouvert Fermé (OCP)

Les entités logicielles doivent être ouvertes pour extension et fermées pour modification.

  1. Principe de substitution de Liskov (LSP)

Un sous-type doit pouvoir remplacer complètement son sur-type.

  1. Principe de ségrégation d'interface (ISP)

Un client ne doit pas dépendre d'interfaces dont il n'a pas besoin.

  1. Principe d'inversion de dépendance (DIP)

Les modules de haut niveau ne doivent pas dépendre de modules de bas niveau, ils doivent dépendre d'interfaces abstraites. Les interfaces abstraites ne doivent pas dépendre d'implémentations concrètes, et les implémentations concrètes doivent dépendre d'interfaces abstraites.

  1. Loi de Déméter (LoD)

Un objet doit avoir une connaissance minimale des autres objets.

  1. Principe de réutilisation par combinaison/agrégation (CARP)

Lorsque vous combinez un groupe d'objets dans un nouvel objet, vous devez utiliser la combinaison/agrégation au lieu de l'héritage pour atteindre l'objectif de réutilisation.

Résumer

Les modèles de conception et les principes de conception sont des concepts très importants dans le développement de logiciels, ils peuvent nous aider à mieux comprendre et concevoir des systèmes logiciels. Cet article présente 23 modèles de conception courants et sept principes de modèle de conception, et fournit des exemples détaillés de démonstrations de code. J'espère que les lecteurs pourront maîtriser ces connaissances grâce à cet article et les appliquer dans le développement réel.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43025343/article/details/131865131
conseillé
Classement