Partage de technologie

Modèle de conception Modèle d'usine

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Factory Pattern est un modèle de conception couramment utilisé dans la programmation orientée objet.modèle de création type de.Le modèle d'usine est principalement utilisé pour créer des objets, mais il est différent de son utilisation directe dans le code.new La création de mots-clés est différente dans la mesure où elle crée des objets via une interface commune, séparant ainsi le processus de création d'objets de l'utilisation du code client. Ce qui suit est une introduction détaillée au modèle d'usine :

1. Principales caractéristiques du modèle d'usine

  1. Le processus de création d'objets encapsulés: Encapsulez le processus de création d'objet dans une classe d'usine.Le client n'a qu'à spécifier le type d'objet qui doit être créé, puis il peut obtenir l'objet requis via la classe d'usine sans se soucier des détails spécifiques de création de l'objet.
  2. Réduire l'accouplement: En isolant l'usine abstraite et l'usine concrète, le couplage entre le client et l'objet est réduit, ce qui rend le programme client plus facile à développer et à maintenir.
  3. Améliorer l’évolutivité du programme: Lorsque vous devez ajouter un nouveau produit, il vous suffit d'ajouter la classe de produit spécifique correspondante et la classe d'usine correspondante. Il n'est pas nécessaire de modifier le code d'origine. Il est conforme au principe d'ouverture-fermeture (ouvert pour extension et fermé). pour modification), ce qui améliore l’évolutivité du code.
  4. Facile à entretenir et à mettre à niveau: Étant donné que la méthode d'usine concentre le processus de création d'objets dans une seule classe, si vous devez modifier la méthode de création d'objets, il vous suffit de modifier la classe d'usine correspondante, et cela n'aura aucun impact sur le client.
  5. réutilisation du code: Le modèle d'usine peut abstraire le processus de création d'objets, réaliser la réutilisation du code et augmenter la flexibilité et la réutilisabilité du code.

2. Classification du modèle d'usine

Les modèles d'usine sont principalement divisés en trois types : le modèle d'usine simple (modèle d'usine statique), le modèle de méthode d'usine et le modèle d'usine abstrait.

1. Méthode d'usine statique
  1. Définissez une classe d'usine pour renvoyer des instances de différentes classes en fonction des différents paramètres transmis.
  2. Les classes Factory contiennent généralement plusieurs méthodes statiques, chaque méthode correspondant à la création d'un produit spécifique.
  3. Avantages : Simple à mettre en œuvre et facile à comprendre.
  4. Inconvénients : Les responsabilités de la classe usine sont trop lourdes. Lors de l'ajout de nouveaux produits, le code source de la classe usine doit être modifié, ce qui viole le principe d'ouverture et de fermeture.

Diagramme de classe de modèle d'usine simple

2. Modèle de méthode d'usine (méthode d'usine)
  1. Définir une interface (usine abstraite) pour créer des objets,Mais laissez la sous-classe décider quelle classe instancier
  2. Les méthodes d'usine permettent de différer l'instanciation de classe vers les sous-classes.
  3. Avantages : Bonne évolutivité Lorsque de nouveaux produits doivent être ajoutés, seules les catégories de produits spécifiques correspondantes et les catégories d'usine spécifiques doivent être ajoutées.
  4. Inconvénients : chaque fois qu'un produit est ajouté, une usine d'implémentation de classe et d'objet spécifique doit être ajoutée, doublant le nombre de classes dans le système et augmentant la complexité du système.

Modèle de méthode d'usine

3. Modèle d'usine abstraite (Abstract Factory)
  1. Fournit une interface pour créer une série d'objets liés ou interdépendants sans spécifier leurs classes concrètes.
  2. Le modèle d'usine abstrait peut être considéré comme l'utilisation conjointe de plusieurs modèles de méthodes d'usine.
  3. Avantages : La famille de produits peut être contrainte au sein de la classe. Une usine spécifique doit être capable de créer tous les produits de la famille de produits.
  4. Inconvénients : Cela augmente l'abstraction et la difficulté de compréhension du système, et le nombre de classes dans le système augmentera considérablement.

modèle d'usine abstrait

3. Scénarios d'application du modèle d'usine

Le modèle d'usine a un large éventail d'applications en développement réel, telles que les connexions de bases de données, les contrôles d'interface utilisateur, le traitement de fichiers, la journalisation, les communications réseau, les files d'attente de messages, les structures de données, le cryptage et le déchiffrement, l'envoi de messages et la planification de tâches. Dans ces scénarios, l'utilisation du modèle d'usine peut séparer le processus de création d'objet du processus d'utilisation, améliorant ainsi la flexibilité et l'évolutivité du système.

4. Exemple de modèle d'usine

1. Exemple de modèle d'usine simple

Dans le modèle de fabrique simple, nous définissons une classe de fabrique qui peut renvoyer des instances de différents types en fonction des paramètres transmis.

Vous trouverez ci-dessous un exemple de modèle d'usine simple écrit en Java. Nous allons créer une usine de formes capable de produire des instances de cercles, de rectangles et de carrés. Tout d’abord, nous définissons une interface de forme (Shape) et plusieurs classes concrètes (Circle, Rectangle, Square) qui implémentent cette interface.

  1. // 形状接口
  2. interface Shape {
  3. void draw();
  4. }
  5. // 圆形类
  6. class Circle implements Shape {
  7. @Override
  8. public void draw() {
  9. System.out.println("Inside Circle::draw() method.");
  10. }
  11. }
  12. // 矩形类
  13. class Rectangle implements Shape {
  14. @Override
  15. public void draw() {
  16. System.out.println("Inside Rectangle::draw() method.");
  17. }
  18. }
  19. // 正方形类
  20. class Square implements Shape {
  21. @Override
  22. public void draw() {
  23. System.out.println("Inside Square::draw() method.");
  24. }
  25. }

Ensuite, nous définissons une classe d'usine (ShapeFactory) qui utilise des méthodes statiques pour générer des objets de forme.

  1. // 形状工厂类
  2. class ShapeFactory {
  3. // 使用 getShape 方法获取形状类型的对象
  4. public static Shape getShape(String shapeType){
  5. if(shapeType == null){
  6. return null;
  7. }
  8. if(shapeType.equalsIgnoreCase("CIRCLE")){
  9. return new Circle();
  10. } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
  11. return new Rectangle();
  12. } else if(shapeType.equalsIgnoreCase("SQUARE")){
  13. return new Square();
  14. }
  15. return null;
  16. }
  17. }

Enfin, nous pouvons utiliser une classe d'usine pour obtenir des objets de forme et appeler leurdrawméthode.

  1. public class FactoryPatternDemo {
  2. public static void main(String[] args) {
  3. // 获取 Circle 的对象,并调用它的 draw 方法
  4. Shape shape1 = ShapeFactory.getShape("CIRCLE");
  5. shape1.draw();
  6. // 获取 Rectangle 的对象,并调用它的 draw 方法
  7. Shape shape2 = ShapeFactory.getShape("RECTANGLE");
  8. shape2.draw();
  9. // 获取 Square 的对象,并调用它的 draw 方法
  10. Shape shape3 = ShapeFactory.getShape("SQUARE");
  11. shape3.draw();
  12. }
  13. }

Dans cet exemple,ShapeFactoryla classe est responsable de la créationShape Une instance de l'interface.Le code client fait cela en transmettant des informations de type (par exemple une chaîne) àShapeFactoryméthode de classe statiquegetShape pour obtenir une instance de la forme souhaitée. De cette façon, le client est découplé de l'implémentation de la classe spécifique et respecte le principe d'ouverture et de fermeture, c'est-à-dire que de nouvelles classes de formes peuvent être étendues sans modifier le code client. Cependant, un inconvénient majeur du modèle d'usine simple est que si le système doit être étendu avec de nouvelles familles de produits (comme des couleurs en plus des formes, etc.), la classe d'usine doit être modifiée, ce qui viole une partie du principe ouvert. -principe fermé. Dans ce cas, envisagez d’utiliser le modèle Factory Method ou le modèle Abstract Factory.

2. Exemple de modèle de méthode d'usine

Toujours à titre d'exemple, nous utilisons des méthodes d'ingénierie pour le créer.

Définissez d’abord l’interface de forme (Produit) et créez trois classes d’implémentation.

  1. // 形状接口
  2. interface Shape {
  3. void draw();
  4. }
  5. // 圆形类
  6. class Circle implements Shape {
  7. @Override
  8. public void draw() {
  9. System.out.println("Inside Circle::draw() method.");
  10. }
  11. }
  12. // 矩形类
  13. class Rectangle implements Shape {
  14. @Override
  15. public void draw() {
  16. System.out.println("Inside Rectangle::draw() method.");
  17. }
  18. }
  19. // 正方形类
  20. class Square implements Shape {
  21. @Override
  22. public void draw() {
  23. System.out.println("Inside Square::draw() method.");
  24. }
  25. }

Ensuite, définissez l'interface du créateur (Creator) et du créateur concret (Concrete Creator) :

  1. // 创建者接口
  2. interface ShapeFactory {
  3. Shape getShape(String shapeType);
  4. }
  5. // 具体创建者类
  6. class RectangleFactory implements ShapeFactory {
  7. @Override
  8. public Shape getShape(String shapeType) {
  9. if (shapeType == null) {
  10. return null;
  11. }
  12. if (shapeType.equalsIgnoreCase("RECTANGLE")) {
  13. return new Rectangle();
  14. }
  15. return null;
  16. }
  17. }
  18. class CircleFactory implements ShapeFactory {
  19. @Override
  20. public Shape getShape(String shapeType) {
  21. if (shapeType == null) {
  22. return null;
  23. }
  24. if (shapeType.equalsIgnoreCase("CIRCLE")) {
  25. return new Circle();
  26. }
  27. return null;
  28. }
  29. }
  30. class SquareFactory implements ShapeFactory {
  31. @Override
  32. public Shape getShape(String shapeType) {
  33. if (shapeType == null) {
  34. return null;
  35. }
  36. if (shapeType.equalsIgnoreCase("SQUARE")) {
  37. return new Square();
  38. }
  39. return null;
  40. }
  41. }

Enfin, utilisez la classe de création concrète pour obtenir les objets de forme et appeler leurdrawméthode:

  1. public class FactoryMethodPatternDemo {
  2. public static void main(String[] args) {
  3. ShapeFactory shapeFactory = new CircleFactory();
  4. // 获取 Circle 的对象,并调用它的 draw 方法
  5. Shape shape1 = shapeFactory.getShape("CIRCLE");
  6. shape1.draw();
  7. // 使用 RectangleFactory 来获取 Rectangle 的对象
  8. shapeFactory = new RectangleFactory();
  9. Shape shape2 = shapeFactory.getShape("RECTANGLE");
  10. shape2.draw();
  11. // 使用 SquareFactory 来获取 Square 的对象
  12. shapeFactory = new SquareFactory();
  13. Shape shape3 = shapeFactory.getShape("SQUARE");
  14. shape3.draw();
  15. }
  16. }

Dans cet exemple,Nous créons une classe d'usine correspondante pour chaque classe de forme (Bien que dans les applications réelles, il y aura généralement une structure de classe d'usine plus générale, peut-être via des fichiers de configuration ou une réflexion pour éviter d'écrire des classes d'usine distinctes pour chaque classe de produit). Cela permet de démontrer les principes de base du modèle Factory Method,Autrement dit, laissez la sous-classe d'usine décider quelle classe instancier . Cependant, pour le cas simple de cet exemple, vous pourriez être plus enclin à utiliser le modèle Simple Factory ou à envisager d'autres modèles de conception pour réduire la duplication de code.

3. Exemple d'usine abstraite

Cet exemple prend les téléphones mobiles comme exemple, abstrait les produits liés aux téléphones mobiles (tels que les écrans, les batteries, les systèmes d'exploitation, etc.) et crée des classes de produits spécifiques pour implémenter ces interfaces. Nous pouvons ensuite définir des interfaces d’usine abstraites et des classes d’usine concrètes pour produire ces produits. Voici un exemple simplifié montrant comment utiliser le modèle Abstract Factory pour produire des composants (écrans et batteries) pour différentes marques et modèles de téléphones mobiles :

Tout d’abord, définissez l’interface du produit et les produits spécifiques :

  1. // 屏幕接口
  2. interface Screen {
  3. void display();
  4. }
  5. // 高端屏幕的实现
  6. class HighEndScreen implements Screen {
  7. @Override
  8. public void display() {
  9. System.out.println("显示高清屏幕");
  10. }
  11. }
  12. // 低端屏幕的实现
  13. class LowEndScreen implements Screen {
  14. @Override
  15. public void display() {
  16. System.out.println("显示普通屏幕");
  17. }
  18. }
  19. // 电池接口
  20. interface Battery {
  21. void charge();
  22. }
  23. // 高效电池的实现
  24. class HighEfficiencyBattery implements Battery {
  25. @Override
  26. public void charge() {
  27. System.out.println("快速充电");
  28. }
  29. }
  30. // 标准电池的实现
  31. class StandardBattery implements Battery {
  32. @Override
  33. public void charge() {
  34. System.out.println("标准充电");
  35. }
  36. }

Ensuite, définissez l'interface de fabrique abstraite et la classe de fabrique concrète :

  1. // 手机组件工厂接口
  2. interface PhoneFactory {
  3. Screen createScreen();
  4. Battery createBattery();
  5. }
  6. // 高端手机工厂
  7. class HighEndPhoneFactory implements PhoneFactory {
  8. @Override
  9. public Screen createScreen() {
  10. return new HighEndScreen();
  11. }
  12. @Override
  13. public Battery createBattery() {
  14. return new HighEfficiencyBattery();
  15. }
  16. }
  17. // 低端手机工厂
  18. class LowEndPhoneFactory implements PhoneFactory {
  19. @Override
  20. public Screen createScreen() {
  21. return new LowEndScreen();
  22. }
  23. @Override
  24. public Battery createBattery() {
  25. return new StandardBattery();
  26. }
  27. }

Enfin, le code client, qui utilise une usine abstraite pour créer des objets produits concrets :

  1. public class PhoneFactoryPatternDemo {
  2. public static void main(String[] args) {
  3. // 使用高端手机工厂
  4. PhoneFactory highEndFactory = new HighEndPhoneFactory();
  5. Screen highEndScreen = highEndFactory.createScreen();
  6. Battery highEndBattery = highEndFactory.createBattery();
  7. highEndScreen.display();
  8. highEndBattery.charge();
  9. // 使用低端手机工厂
  10. PhoneFactory lowEndFactory = new LowEndPhoneFactory();
  11. Screen lowEndScreen = lowEndFactory.createScreen();
  12. Battery lowEndBattery = lowEndFactory.createBattery();
  13. lowEndScreen.display();
  14. lowEndBattery.charge();
  15. }
  16. }

Dans cet exemple, nous définissons deux usines de téléphonie mobile (haut de gamme et bas de gamme), chacune capable de produire un type d'écran et de batterie spécifique.Le code client interagit avec la classe d'usine spécifique via l'interface d'usine abstraite, réalisant ainsi le découplage de la classe de produit spécifique. . De cette façon, si nous devons ajouter de nouveaux types de téléphones à l'avenir (par exemple, des téléphones de milieu de gamme), il nous suffit d'ajouter de nouvelles classes de produits et les classes d'usine correspondantes sans modifier le code client existant.

5. Résumé

Le modèle d'usine est un modèle de conception très utile,Il encapsule le processus de création d'objets, réduit le couplage, améliore l'évolutivité du programme et la facilité de maintenance, etc. , a été largement utilisé dans le développement de logiciels.Cependant, il comporte également certainsInconvénients, tels que des responsabilités excessives de l'usine, des difficultés d'expansion du système, etc. . Par conséquent, dans les applications pratiques, des compromis et des choix doivent être faits en fonction de scénarios et de besoins spécifiques.

Si le modèle d'usine (usine simple, méthode d'usine, usine abstraite) vous est utile, pensez à l'aimer et à le collectionner.