logo

Fabriksmetod Designmönster

Fabriksmetodens designmönster är en kreativt designmönster som ger ett gränssnitt för att skapa objekt i en superklass, vilket tillåter underklasser att ändra typen av objekt som kommer att skapas. Det kapslar in objektskapande logik i en separat metod, vilket främjar lös koppling mellan skaparen och de skapade objekten. Det här mönstret är särskilt användbart när de exakta typerna av objekt som ska skapas kan variera eller måste bestämmas under körning, vilket möjliggör flexibilitet och utökningsbarhet vid objektskapande.

Innehållsförteckning



Vad är fabriksmetodens designmönster?

Factory Method Design Pattern är ett kreativt designmönster som används inom mjukvaruteknik för att tillhandahålla ett gränssnitt för att skapa objekt i en superklass, samtidigt som underklasser kan ändra typen av objekt som kommer att skapas. Den kapslar in logiken för att skapa objekt i en separat metod, abstraherar instansieringsprocessen och främjar en lös koppling mellan skaparen och de skapade objekten. Detta mönster möjliggör flexibilitet, utökbarhet och underhållbarhet i kodbasen genom att tillåta underklasser att definiera sin egen implementering av fabriksmetoden för att skapa specifika typer av objekt.

personalvalskommissionens betydelse

När ska man använda Factory Method Design Pattern?

Använd fabriksmetodens designmönster:

  • När du vill kapsla in objektskapande: Om du har en komplex process för att skapa objekt eller om processen kan variera beroende på förhållandena, kan inkapsling av denna logik i en fabriksmetod förenkla klientkoden och främja återanvändbarhet.
  • När du vill frikoppla klientkod från konkreta klasser: Genom att använda Factory Method Pattern kan du skapa objekt genom ett gränssnitt eller en abstrakt klass, och abstraherar bort de specifika implementeringsdetaljerna för de konkreta klasserna från klientkoden. Detta främjar lös koppling och gör det lättare att modifiera eller utöka systemet utan att påverka befintlig klientkod.
  • När du behöver stödja flera produktvarianter: Om din applikation behöver skapa olika varianter av en produkt eller om nya typer av produkter kan komma att introduceras i framtiden, ger Factory Method Pattern ett flexibelt sätt att tillgodose dessa variationer genom att definiera fabriksmetoder för varje produkttyp.
  • När du vill stödja anpassning eller konfiguration: Fabriker kan användas för att kapsla in konfigurationslogik, vilket gör att klienter kan anpassa skapelseprocessen genom att tillhandahålla parametrar eller konfigurationsalternativ till fabriksmetoden.

Komponenter i Factory Method Design Pattern

1. Skapare

Detta är en abstrakt klass eller ett gränssnitt som deklarerar fabriksmetoden. Skaparen innehåller vanligtvis en metod som fungerar som en fabrik för att skapa objekt. Den kan också innehålla andra metoder som fungerar med de skapade objekten.

2. Concrete Creator

Concrete Creator-klasser är underklasser av Creator som implementerar fabriksmetoden för att skapa specifika typer av objekt. Varje betongskapare är ansvarig för att skapa en viss produkt.

lycka till

3. Produkt

Detta är gränssnittet eller den abstrakta klassen för objekten som fabriksmetoden skapar. Produkten definierar det gemensamma gränssnittet för alla objekt som fabriksmetoden kan skapa.

4. Betongprodukt

Konkreta produktklasser är de faktiska objekt som fabriksmetoden skapar. Varje Concrete Product-klass implementerar produktgränssnittet eller utökar produktens abstrakta klass.

Exempel på designmönster för fabriksmetod

Nedan är problemformuleringen för att förstå Factory Method Design Pattern:

Överväg ett program som behöver hantera skapandet av olika typer av fordon, såsom tvåhjulingar, trehjulingar och fyrhjulingar. Varje typ av fordon har sina egna specifika egenskaper och beteenden.

1. Utan fabriksmetoddesignmönster

Java
/*package whatever //do not write package name here */ import java.io.*; // Library classes abstract class Vehicle {  public abstract void printVehicle(); } class TwoWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am two wheeler');  } } class FourWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am four wheeler');  } } // Client (or user) class class Client {  private Vehicle pVehicle;  public Client(int type) {  if (type == 1) {  pVehicle = new TwoWheeler();  } else if (type == 2) {  pVehicle = new FourWheeler();  } else {  pVehicle = null;  }  }  public void cleanup() {  if (pVehicle != null) {  pVehicle = null;  }  }  public Vehicle getVehicle() {  return pVehicle;  } } // Driver program public class GFG {  public static void main(String[] args) {  Client pClient = new Client(1);  Vehicle pVehicle = pClient.getVehicle();  if (pVehicle != null) {  pVehicle.printVehicle();  }  pClient.cleanup();  } }>
Produktion
I am two wheeler>

Vilka är problemen med ovanstående design?

I ovanstående koddesign:

  • Tät koppling: KlientklassenClient>instansierar direkt betongklasserna (TwoWheeler>ochFourWheeler>) baserat på den inmatningstyp som angavs under dess konstruktion. Detta leder till en tät koppling mellan byggherren och betongklasserna, vilket gör koden svår att underhålla och utöka.
  • Brott mot principen om ett enda ansvar (SRP): DeClient>klass ansvarar inte bara för att bestämma vilken typ av fordon som ska instansieras baserat på ingångstypen utan också för att hantera fordonsobjektets livscykel (t.ex. sanering). Detta bryter mot Single Responsibility Principle, som säger att en klass bara ska ha en anledning att byta.
  • Begränsad skalbarhet: Att lägga till en ny typ av fordon kräver modifiering avClient>klass, vilket bryter mot Open-Closed-principen. Denna design är inte skalbar eftersom den inte kan ta emot nya typer av fordon utan att ändra befintlig kod.

Hur undviker vi problemet?

  • Definiera fabriksgränssnitt: Skapa enVehicleFactory>gränssnitt eller abstrakt klass med en metod för att skapa fordon.
  • Implementera betongfabriker: Implementera betongfabriksklasser (TwoWheelerFactory>ochFourWheelerFactory>) som implementerarVehicleFactory>gränssnitt och tillhandahåller metoder för att skapa instanser av specifika typer av fordon.
  • Refactor-klient: ÄndraClient>klass att acceptera enVehicleFactory>istället för att direkt instansiera fordon. Kunden kommer att begära ett fordon från fabriken, vilket eliminerar behovet av villkorad logik baserad på fordonstyper.
  • Förbättrad flexibilitet: Med detta tillvägagångssätt är det lika enkelt att lägga till nya typer av fordon som att skapa en ny fabriksklass för den nya fordonstypen utan att ändra befintlig kundkod.

2. Med fabriksmetoddesignmönster

Låt oss dela upp koden i komponentvis kod:

FactoryMethodDesignPattern

1. Produktgränssnitt

Java
// Product interface representing a vehicle public abstract class Vehicle {  public abstract void printVehicle(); }>

2. Betongprodukter

Java
// Concrete product classes representing different types of vehicles public class TwoWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am two wheeler');  } } public class FourWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am four wheeler');  } }>

3. Skapargränssnitt (fabriksgränssnitt)

Java
// Factory interface defining the factory method public interface VehicleFactory {  Vehicle createVehicle(); }>

4. Betongskapare (betongfabriker)

Java
// Concrete factory class for TwoWheeler public class TwoWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new TwoWheeler();  } } // Concrete factory class for FourWheeler public class FourWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new FourWheeler();  } }>

Komplett kod för detta exempel:

Java
// Library classes abstract class Vehicle {  public abstract void printVehicle(); } class TwoWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am two wheeler');  } } class FourWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am four wheeler');  } } // Factory Interface interface VehicleFactory {  Vehicle createVehicle(); } // Concrete Factory for TwoWheeler class TwoWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new TwoWheeler();  } } // Concrete Factory for FourWheeler class FourWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new FourWheeler();  } } // Client class class Client {  private Vehicle pVehicle;  public Client(VehicleFactory factory) {  pVehicle = factory.createVehicle();  }  public Vehicle getVehicle() {  return pVehicle;  } } // Driver program public class GFG {  public static void main(String[] args) {  VehicleFactory twoWheelerFactory = new TwoWheelerFactory();  Client twoWheelerClient = new Client(twoWheelerFactory);  Vehicle twoWheeler = twoWheelerClient.getVehicle();  twoWheeler.printVehicle();  VehicleFactory fourWheelerFactory = new FourWheelerFactory();  Client fourWheelerClient = new Client(fourWheelerFactory);  Vehicle fourWheeler = fourWheelerClient.getVehicle();  fourWheeler.printVehicle();  } }>
Produktion
I am two wheeler I am four wheeler>

I ovanstående kod:

namnkonvention för java
  • Vehicle> fungerar som produktgränssnittet och definierar den vanliga metoden printVehicle()> som alla betongprodukter måste genomföra.
  • TwoWheeler> och FourWheeler> är konkreta produktklasser som representerar olika typer av fordon och implementerar printVehicle()> metod.
  • VehicleFactory> fungerar som Skapargränssnittet (Factory Interface) med en metod createVehicle()> representerar fabriksmetoden.
  • TwoWheelerFactory> och FourWheelerFactory> är betongskaparklasser (betongfabriker) som implementerar VehicleFactory> gränssnitt för att skapa instanser av specifika typer av fordon.

Användningsfall av fabriksmetodens designmönster

Här är några vanliga tillämpningar av Factory Method Design-mönster:

  • Skapande ramar:
    • JDBC (Java Database Connectivity) använder fabriker i stor utsträckning för att skapa anslutningar, uttalanden och resultatuppsättningar. Ramverk för beroendeinjektion som Spring och Guice är starkt beroende av fabriker för att skapa och hantera bönor.
  • GUI Toolkit:
    • Swing och JavaFX använder fabriker för att skapa UI-komponenter som knappar, textfält och etiketter, vilket möjliggör anpassning och flexibilitet i UI-design.
  • Loggningsramar:
    • Loggningsramverk som Log4j och Logback använder fabriker för att skapa loggrar med olika konfigurationer, vilket möjliggör kontroll över loggningsnivåer och utdatadestinationer.
  • Serialisering och deserialisering:
    • Objektserialiseringsramverk använder ofta fabriker för att skapa objekt från serialiserade data, som stöder olika serialiseringsformat och versionshantering.
  • Pluginsystem:
    • Plugin-baserade system använder ofta fabriker för att ladda och skapa plugin-instanser dynamiskt, vilket möjliggör utökning och anpassning.
  • Spelutveckling:
    • Spelmotorer använder ofta fabriker för att skapa olika typer av spelobjekt, karaktärer och nivåer, vilket främjar kodorganisation och flexibilitet.
  • Webbutveckling:
    • Webbramverk använder ibland fabriker för att skapa vykomponenter, kontroller och tjänster, vilket möjliggör modularitet och testbarhet i webbapplikationer.

Fördelar med Factory Method Design Pattern

Fördelarna med Factory Method Design Pattern är:

array av strängar c programmering
  • Frikoppling: Den separerar objektskapande logik från klientkoden som använder dessa objekt. Detta gör koden mer flexibel och underhållbar eftersom ändringar i skapandeprocessen inte kräver modifieringar av klientkoden.
  • Sträckbarhet: Det är enkelt att introducera nya produkttyper utan att ändra kundkoden. Du behöver helt enkelt skapa en ny Concrete Creator-underklass och implementera fabriksmetoden för att producera den nya produkten.
  • Testbarhet: Det förenklar enhetstestning genom att låta dig håna eller stumma produktskapandet under tester. Du kan testa olika produktimplementeringar isolerat utan att förlita dig på faktisk objektskapande.
  • Kodåteranvändbarhet: Fabriksmetoden kan återanvändas i olika delar av applikationen där objektskapande behövs. Detta främjar centralisering och återanvändning av objektskapande logik.
  • Inkapsling: Den döljer de konkreta produktklasserna från klientkoden, vilket gör koden mindre beroende av specifika implementeringar. Detta förbättrar underhållsbarheten och minskar kopplingen.

Nackdelar med Factory Method Design Pattern

Nackdelarna med Factory Method Design Pattern är:

  • Ökad komplexitet: Den introducerar ytterligare klasser och gränssnitt och lägger till ett lager av abstraktion som kan göra koden mer komplex att förstå och underhålla, särskilt för de som inte känner till mönstret.
  • Över huvudet: Användningen av polymorfism och dynamisk bindning kan påverka prestandan något, även om detta ofta är försumbart i de flesta applikationer.
  • Tät koppling inom produkthierarkier: Concrete Creators är fortfarande tätt kopplade till sina motsvarande betongprodukter. Förändringar av den ena kräver ofta förändringar av den andra.
  • Beroende av betongunderklasser: Klientkoden beror fortfarande på den abstrakta Creator-klassen, som kräver kunskap om dess konkreta underklasser för att göra korrekta fabriksmetodanrop.
  • Potential för överanvändning: Det är viktigt att använda Factory Method-mönstret med omtanke för att undvika att överkonstruera applikationen. Enkelt objektskapande kan ofta hanteras direkt utan behov av en fabrik.
  • Testutmaningar: Att testa själva fabrikslogiken kan vara mer komplicerat.