Technologieaustausch

Designmuster-Fabrikmuster

2024-07-12

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

Factory Pattern ist ein Entwurfsmuster, das häufig in der objektorientierten Programmierung verwendet wirdSchöpfungsmuster So'ne Art.Das Factory-Muster wird hauptsächlich zum Erstellen von Objekten verwendet, unterscheidet sich jedoch von der direkten Verwendung im Code.new Der Unterschied bei der Schlüsselworterstellung besteht darin, dass Objekte über eine gemeinsame Schnittstelle erstellt werden, wodurch der Objekterstellungsprozess von der Verwendung von Clientcode getrennt wird. Im Folgenden finden Sie eine detaillierte Einführung in das Fabrikmuster:

1. Hauptmerkmale des Werksmodells

  1. Der Erstellungsprozess gekapselter Objekte: Kapseln Sie den Objekterstellungsprozess in einer Factory-Klasse. Der Client muss nur den Typ des zu erstellenden Objekts angeben und kann dann das erforderliche Objekt über die Factory-Klasse abrufen, ohne sich um die spezifischen Erstellungsdetails des Objekts zu kümmern.
  2. Kopplung reduzieren: Durch die Isolierung der abstrakten Fabrik und der konkreten Fabrik wird die Kopplung zwischen dem Client und dem Objekt verringert, wodurch das Client-Programm einfacher zu erweitern und zu warten ist.
  3. Verbessern Sie die Skalierbarkeit des Programms: Wenn Sie ein neues Produkt hinzufügen müssen, müssen Sie nur die entsprechende spezifische Produktklasse und die entsprechende Fabrikklasse hinzufügen. Es ist nicht erforderlich, den ursprünglichen Code zu ändern. Er entspricht dem Open-Close-Prinzip (offen zur Erweiterung und geschlossen). zur Änderung), was die Skalierbarkeit des Codes verbessert.
  4. Einfache Wartung und Aufrüstung: Da die Factory-Methode den Prozess zum Erstellen von Objekten in einer Klasse konzentriert, müssen Sie zum Ändern der Methode zum Erstellen von Objekten nur die entsprechende Factory-Klasse ändern. Dies hat keine Auswirkungen auf den Client.
  5. Wiederverwendung von Code: Das Factory-Muster kann den Objekterstellungsprozess abstrahieren, die Wiederverwendung von Code realisieren und die Flexibilität und Wiederverwendbarkeit des Codes erhöhen.

2. Klassifizierung des Werksmodells

Fabrikmuster werden hauptsächlich in drei Typen unterteilt: einfache Fabrikmuster (statische Fabrikmuster), Fabrikmethodenmuster und abstrakte Fabrikmuster.

1. Statische Fabrikmethode
  1. Definieren Sie eine Factory-Klasse, um Instanzen verschiedener Klassen basierend auf den verschiedenen übergebenen Parametern zurückzugeben.
  2. Factory-Klassen enthalten normalerweise mehrere statische Methoden, wobei jede Methode der Erstellung eines bestimmten Produkts entspricht.
  3. Vorteile: Einfach zu implementieren und leicht zu verstehen.
  4. Nachteile: Die Verantwortlichkeiten der Factory-Klasse sind zu groß. Beim Hinzufügen neuer Produkte muss der Quellcode der Factory-Klasse geändert werden, was gegen das Öffnungs- und Schließprinzip verstößt.

Einfaches Fabrikmuster-Klassendiagramm

2. Factory-Methodenmuster (Factory-Methode)
  1. Definieren Sie eine Schnittstelle (abstrakte Fabrik) zum Erstellen von Objekten.Aber lassen Sie die Unterklasse entscheiden, welche Klasse instanziiert werden soll
  2. Mit Factory-Methoden kann die Klasseninstanziierung auf Unterklassen verschoben werden.
  3. Vorteile: Gute Skalierbarkeit. Wenn neue Produkte hinzugefügt werden müssen, müssen nur die entsprechenden spezifischen Produktkategorien und spezifischen Fabrikkategorien hinzugefügt werden.
  4. Nachteile: Jedes Mal, wenn ein Produkt hinzugefügt wird, muss eine bestimmte Klassen- und Objektimplementierungsfabrik hinzugefügt werden, wodurch sich die Anzahl der Klassen im System verdoppelt und die Komplexität des Systems erhöht.

Factory-Methodenmuster

3. Abstraktes Fabrikmuster (Abstrakte Fabrik)
  1. Stellt eine Schnittstelle zum Erstellen einer Reihe verwandter oder voneinander abhängiger Objekte bereit, ohne deren konkrete Klassen anzugeben.
  2. Das abstrakte Fabrikmuster kann als die gemeinsame Verwendung mehrerer Fabrikmethodenmuster angesehen werden.
  3. Vorteile: Die Produktfamilie kann innerhalb der Klasse eingeschränkt werden. Eine bestimmte Fabrik muss in der Lage sein, alle Produkte der Produktfamilie zu erstellen.
  4. Nachteile: Es erhöht die Abstraktion und die Schwierigkeit, das System zu verstehen, und die Anzahl der Klassen im System wird erheblich zunehmen.

abstraktes Fabrikmuster

3. Anwendungsszenarien des Fabrikmodells

Das Factory-Muster hat in der tatsächlichen Entwicklung ein breites Anwendungsspektrum, z. B. Datenbankverbindungen, UI-Steuerelemente, Dateiverarbeitung, Protokollierung, Netzwerkkommunikation, Nachrichtenwarteschlangen, Datenstrukturen, Verschlüsselung und Entschlüsselung, Nachrichten-Push und Aufgabenplanung. In diesen Szenarien kann die Verwendung des Factory-Musters den Objekterstellungsprozess vom Nutzungsprozess trennen und so die Flexibilität und Skalierbarkeit des Systems verbessern.

4. Beispiel für ein Fabrikmodell

1. Beispiel für ein einfaches Factory-Muster

Im einfachen Factory-Muster definieren wir eine Factory-Klasse, die basierend auf den übergebenen Parametern Instanzen verschiedener Typen zurückgeben kann.

Unten finden Sie ein Beispiel für ein einfaches Factory-Muster, das in Java geschrieben wurde. Wir werden eine Formfabrik erstellen, die Instanzen von Kreisen, Rechtecken und Quadraten erzeugen kann. Zunächst definieren wir eine Formschnittstelle (Shape) und mehrere konkrete Klassen (Circle, Rechteck, Quadrat), die diese Schnittstelle implementieren.

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

Als Nächstes definieren wir eine Factory-Klasse (ShapeFactory), die statische Methoden zum Generieren von Formobjekten verwendet.

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

Schließlich können wir eine Factory-Klasse verwenden, um Formobjekte abzurufen und sie aufzurufendrawMethode.

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

In diesem Beispiel,ShapeFactoryDie Klasse ist für die Erstellung verantwortlichShape Eine Instanz der Schnittstelle.Der Clientcode tut dies, indem er Typinformationen (z. B. eine Zeichenfolge) an übergibtShapeFactorystatische Methode der KlassegetShape um eine Instanz der gewünschten Form zu erhalten. Auf diese Weise ist der Client von der Implementierung der spezifischen Klasse entkoppelt und entspricht dem Öffnungs- und Schließprinzip, d. h. neue Formklassen können erweitert werden, ohne den Client-Code zu ändern. Ein großer Nachteil des einfachen Fabrikmusters besteht jedoch darin, dass die Fabrikklasse geändert werden muss, wenn das System um neue Produktfamilien (z. B. Farben zusätzlich zu Formen usw.) erweitert werden muss, was einen Teil der Offenheit verletzt -geschlossenes Prinzip. Erwägen Sie in diesem Fall die Verwendung des Factory-Methode-Musters oder des Abstract-Factory-Musters.

2. Beispiel für ein Factory-Methodenmuster

Wir nehmen immer noch die Form als Vorbild und nutzen technische Methoden, um sie zu schaffen.

Definieren Sie zunächst die Formschnittstelle (Produkt) und erstellen Sie drei Implementierungsklassen.

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

Als nächstes definieren Sie die Erstellerschnittstelle (Creator) und den konkreten Ersteller (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. }

Verwenden Sie abschließend die konkrete Creator-Klasse, um die Formobjekte abzurufen und aufzurufendrawMethode:

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

In diesem Beispiel,Wir erstellen für jede Formklasse eine entsprechende Factory-Klasse (Obwohl es in realen Anwendungen normalerweise eine allgemeinere Factory-Klassenstruktur gibt, möglicherweise durch Konfigurationsdateien oder Reflektion, um das Schreiben separater Factory-Klassen für jede Produktklasse zu vermeiden). Dies hilft dabei, die Grundprinzipien des Factory-Methode-Musters zu demonstrieren.Das heißt, lassen Sie die Factory-Unterklasse entscheiden, welche Klasse instanziiert werden soll . Für den einfachen Fall in diesem Beispiel sind Sie jedoch möglicherweise eher geneigt, das Simple Factory-Muster zu verwenden oder andere Entwurfsmuster in Betracht zu ziehen, um die Codeduplizierung zu reduzieren.

3. Abstraktes Fabrikbeispiel

In diesem Beispiel werden Mobiltelefone als Beispiel verwendet, abstrakte Produkte im Zusammenhang mit Mobiltelefonen (z. B. Bildschirme, Akkus, Betriebssysteme usw.) werden verwendet und spezifische Produktklassen zur Implementierung dieser Schnittstellen erstellt. Anschließend können wir abstrakte Fabrikschnittstellen und konkrete Fabrikklassen definieren, um diese Produkte herzustellen. Hier ist ein vereinfachtes Beispiel, das zeigt, wie das Abstract Factory-Muster verwendet wird, um Komponenten (Bildschirme und Batterien) für verschiedene Marken und Modelle von Mobiltelefonen herzustellen:

Definieren Sie zunächst die Produktschnittstelle und bestimmte Produkte:

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

Als nächstes definieren Sie die abstrakte Factory-Schnittstelle und die konkrete Factory-Klasse:

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

Schließlich der Client-Code, der eine abstrakte Fabrik verwendet, um konkrete Produktobjekte zu erstellen:

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

In diesem Beispiel definieren wir zwei Mobiltelefonfabriken (High-End- und Low-End-Fabriken), die jeweils in der Lage sind, einen bestimmten Bildschirm- und Akkutyp herzustellen.Der Clientcode interagiert über die abstrakte Factory-Schnittstelle mit der spezifischen Factory-Klasse und erreicht so eine Entkopplung von der spezifischen Produktklasse. . Wenn wir in Zukunft neue Telefontypen hinzufügen müssen (z. B. Mittelklasse-Telefone), müssen wir auf diese Weise nur neue Produktklassen und entsprechende Fabrikklassen hinzufügen, ohne den vorhandenen Client-Code zu ändern.

5. Zusammenfassung

Das Fabrikmuster ist ein sehr nützliches Designmuster.Es kapselt den Erstellungsprozess von Objekten, reduziert die Kopplung, verbessert die Programmskalierbarkeit und Wartungsfreundlichkeit usw. ist in der Softwareentwicklung weit verbreitet.Allerdings hat es auch welcheNachteile wie übermäßige Fabrikverantwortung, Schwierigkeiten bei der Systemerweiterung usw. . Daher müssen in praktischen Anwendungen Kompromisse und Entscheidungen auf der Grundlage spezifischer Szenarien und Bedürfnisse getroffen werden.

Wenn das Fabrikmuster (einfache Fabrik, Fabrikmethode, abstrakte Fabrik) für Sie nützlich ist, denken Sie daran, es zu mögen und zu sammeln.