[JAVA] Modèle de conception du GoF à partir du problème 1. Génération

Les modèles de conception sont souvent décrits comme «des problèmes fréquemment rencontrés et leurs solutions». Lors de la conception, il y a d'abord un problème et nous cherchons une solution (modèle) pour cela. Il existe de nombreux articles résumés par modèle → problème → exemple, mais j'ai senti qu'il y avait peu d'articles résumés par problème → modèle → exemple, alors je l'ai écrit. C'est juste au cas où je ferais face au même problème moi-même, mais j'espère que cela aide. Je vous serais reconnaissant si vous pouviez me faire savoir s'il y a quelque chose qui ne va pas ou quelque chose qui peut être amélioré. De plus, seul le cas où le modèle de conception GoF est appliqué lors de la conception avec Java est traité ici. Veuillez également vous référer à ici car nous n'écrirons pas une liste de modèles ou une description de chaque modèle.

  1. Génération
  2. Structure
  3. Comportement

Sera ajouté à tout moment

: question: je veux donner au constructeur un nom descriptif

before

public class FooClient {

  private final String url;
  private final String proxyHost;
  private final int proxyPort;

  public FooClient(String url) {
    this.url = url;
    this.proxyHost = null;
    this.proxyPort = -1;
  }

  public FooClient(String url, String proxyHost, int proxyPort) {
    this.url = url;
    this.proxyHost = proxyHost;
    this.proxyPort = proxyPort;
  }
}
new FooClient(url);
new FooClient(url, proxyHost, proxyPort);

Je ne pense pas que ce soit mauvais pour une implémentation normale, mais il y a des cas où vous voulez être clair avec et sans proxy.

after :bulb: Factory Method

public class FooClient {

  private final String url;
  private final String proxyHost;
  private final int proxyPort;

  private FooClient(String url, String proxyHost, int proxyPort) {
    this.url = url;
    this.proxyHost = proxyHost;
    this.proxyPort = proxyPort;
  }

  public static FooClient withoutProxy(String url) {
    return new FooClient(url, null, -1);
  }

  public static FooClient withProxy(String url, String proxyHost, int proxyPort) {
    return new FooClient(url, proxyHost, proxyPort);
  }
}
FooClient.withoutProxy(url);
FooClient.withProxy(url, proxyHost, proxyPort);

Il est plus facile de comprendre si un proxy est utilisé ou non. (Surtout quand "non utilisé")

: question: je souhaite renvoyer une instance en fonction de la condition de la sous-classe sans avertir l'utilisateur

before

public class FooDateFilter extends FooFilter {}
public class FooNumberFilter extends FooFilter {}
public class FooStringFilter extends FooFilter {}
FooFilter filter = new FooStringFilter("foo");

Ce serait bien d'avoir une interface qui renvoie une instance de la sous-classe en fonction de l'argument.

after :bulb: FactoryMethod

public class FooDateFilter extends FooFilter {}
public class FooNumberFilter extends FooFilter {}
public class FooStringFilter extends FooFilter {}

public class FooFilterFactory {

  private FooFilterFactory() {}

  public static FooFilter create(Date date) {
    return new FooDateFilter(date);
  }

  public static FooFilter create(Number number) {
    return new FooNumberFilter(number);
  }

  public static FooFilter create(String string) {
    return new FooStringFilter(string);
  }
}
FooFilter filter = FooFilterFactory.create("foo");

L'utilisateur n'a plus besoin de savoir ce qu'il y a dans la sous-classe. De plus, si l'une des sous-classes est abolie à l'avenir et que vous souhaitez utiliser une nouvelle classe, vous pouvez simplement modifier la fabrique et l'utilisateur n'en sera pas conscient.

: question: je veux définir un par un car il y a beaucoup de champs, mais je veux le rendre immuable après le réglage

before

public class FooWindow {

  private final int width;
  private final int height;
  private final FooColor color;
  private final FooColor backgroundColor;

  public FooWindow() {
    this.width = 0;
    this.height = 0;
    this.color = null;
    this.backgroundColor = null;
  }

  public FooWindow(int width, int height, FooColor color, FooColor backgroundColor) {
    this.width = width;
    this.height = height;
    this.color = color;
    this.backgroundColor = backgroundColor;
  }

  public FooWindow withWidth(int width) {
    return new FooWindow(width, this.height, this.color, this.backgroundColor);
  }

  public FooWindow withHeight(int height) {
    return new FooWindow(this.width, height, this.color, this.backgroundColor);
  }

Sous la couleur,Méthode similaire pour backgroundColor
}
new FooWindow()
  .withWidth(100)
  .withHeight(200)
  .withColor(color)
  .withBackgroundColor(backgroundColor);

Il est inutile de créer une instance à chaque fois. Si mutable est acceptable, vous pouvez le remplacer dans votre propre champ par withWidth. (Ce n'est pas un modèle GoF, mais c'est un modèle appelé Fluent Setter ou Wither)

after :bulb: Builder

public class FooWindow {

  private final int width;
  private final int height;
  private final FooColor color;
  private final FooColor backgroundColor;

  public FooWindow(int width, int height, FooColor color, FooColor backgroundColor) {
    this.width = width;
    this.height = height;
    this.color = color;
    this.backgroundColor = backgroundColor;
  }

  public static class FooWindowBuilder {

    private int width;
    private int height;
    private FooColor color;
    private FooColor backgroundColor;

    public FooWindowBuilder withWidth(int width) {
      this.width = width;
      return this;
    }

    public FooWindowBuilder withHeight(int height) {
      this.height = height;
      return this;
    }

Sous la couleur,Méthode similaire pour backgroundColor

    public FooWindow build() {
      return new FooWindow(this.width, this.height, this.color, this.backgroundColor);
    }
  }
}
new FooWindowBuilder()
  .withWidth(100)
  .withHeight(200)
  .withColor(color)
  .withBackgroundColor(backgroundColor)
  .build();

La génération d'instance a été supprimée. Si le nombre de champs est de quatre comme dans cet exemple, je pense qu'il n'y a toujours pas de problème avec le constructeur, mais à mesure que le nombre augmente encore, il devient difficile de savoir quel argument numérique représente quoi. Dans de tels cas, considérez le modèle Builder.

Recommended Posts

Modèle de conception du GoF à partir du problème 1. Génération
Modèle de conception du GoF à partir du problème 2. Structure
Modèle de conception GoF à partir du problème 3. Comportement
Résumé du modèle de conception Java GoF
Apprenez le modèle de conception "Builder" avec Python
Apprenez le modèle de conception "Flyweight" en Python
Apprenez le modèle de conception "Observer" en Python
Apprenez le modèle de conception "Memento" avec Python
Apprenez le modèle de conception "Proxy" en Python
Apprenez le modèle de conception "Visiteur" avec Python
Apprenez le modèle de conception "Bridge" avec Python
Apprenez le modèle de conception "Mediator" avec Python
Apprenez le modèle de conception "Décorateur" avec Python
Apprenez le modèle de conception "Iterator" avec Python
Apprenez le modèle de conception «Stratégie» avec Python
Apprenez le modèle de conception "Composite" avec Python
Apprenez le modèle de conception "Singleton" avec Python
Apprenez le modèle de conception "État" en Python
Apprenez le modèle de conception "Adapter" avec Python
Apprenez le modèle de conception "Façade" avec Python
Modèle de conception #Builder
Apprenez le modèle de conception "Abstract Factory" avec Python
Modèle de conception #Decorator
Apprenez le modèle de conception "Méthode de modèle" en Python
Modèle de conception #Observer
Apprenez le modèle de conception "Méthode d'usine" en Python
Modèle de conception #Facade
Modèle de conception #Strategy
Modèle de conception #Singleton
Modèle de conception #Proxy
Apprenez le modèle de conception «Chaîne de responsabilité» en Python
Design Pattern #Factory, méthode
Problème de conception du réseau logistique
Design Pattern #Template, méthode
À propos du modèle de visiteur
Examiner le double problème
L'histoire selon laquelle les modèles de conception du GoF ne sont rien de plus qu'une «introduction de couches abstraites»
Problème de placement d'ambulance - Tiré du numéro d'octobre du magazine OR