Het ontwerppatroon van de fabrieksmethode is een creatie ontwerppatroon dat een interface biedt voor het maken van objecten in een superklasse, waardoor subklassen het type objecten kunnen wijzigen dat wordt gemaakt. Het omvat de logica voor het maken van objecten in een aparte methode, waardoor een losse koppeling tussen de maker en de gemaakte objecten wordt bevorderd. Dit patroon is met name handig wanneer de exacte typen objecten die moeten worden gemaakt, kunnen variëren of tijdens runtime moeten worden bepaald, waardoor flexibiliteit en uitbreidbaarheid bij het maken van objecten mogelijk wordt.
Inhoudsopgave
- Wat is het ontwerppatroon van de fabrieksmethode?
- Wanneer gebruik ik het Factory Method Design Pattern?
- Onderdelen van het ontwerppatroon van de fabrieksmethode
- Fabrieksmethode Ontwerppatroonvoorbeeld
- Gebruiksscenario's van het ontwerppatroon van de fabrieksmethode
- Voordelen van het fabrieksmethodeontwerppatroon
- Nadelen van het ontwerppatroon van de fabrieksmethode
Wat is het ontwerppatroon van de fabrieksmethode?
Het Factory Method Design Pattern is een creatief ontwerppatroon dat in de software-engineering wordt gebruikt om een interface te bieden voor het maken van objecten in een superklasse, terwijl subklassen het type objecten kunnen wijzigen dat wordt gemaakt. Het vat de logica voor het maken van objecten samen in een aparte methode, waarbij het instantiatieproces wordt geabstraheerd en een losse koppeling tussen de maker en de gecreëerde objecten wordt bevorderd. Dit patroon maakt flexibiliteit, uitbreidbaarheid en onderhoudbaarheid in de codebase mogelijk door subklassen toe te staan hun eigen implementatie van de fabrieksmethode te definiëren om specifieke typen objecten te creëren.
logica van de eerste orde
Wanneer gebruik ik het Factory Method Design Pattern?
Gebruik het ontwerppatroon van de fabrieksmethode:
- Wanneer u het maken van objecten wilt inkapselen: Als u een complex objectcreatieproces heeft of als het proces kan variëren op basis van omstandigheden, kan het inkapselen van deze logica in een fabrieksmethode de clientcode vereenvoudigen en de herbruikbaarheid bevorderen.
- Wanneer u clientcode wilt ontkoppelen van concrete klassen: Met behulp van het Factory Method Pattern kunt u objecten maken via een interface of abstracte klasse, waarbij u de specifieke implementatiedetails van de concrete klassen uit de clientcode abstraheert. Dit bevordert de losse koppeling en maakt het gemakkelijker om het systeem aan te passen of uit te breiden zonder de bestaande clientcode te beïnvloeden.
- Wanneer u meerdere productvarianten moet ondersteunen: Als uw toepassing verschillende varianten van een product moet maken of als er in de toekomst nieuwe typen producten worden geïntroduceerd, biedt het Factory Method Pattern een flexibele manier om aan deze variaties tegemoet te komen door fabrieksmethoden voor elk producttype te definiëren.
- Wanneer u maatwerk of configuratie wilt ondersteunen: Fabrieken kunnen worden gebruikt om configuratielogica in te kapselen, waardoor klanten het creatieproces kunnen aanpassen door parameters of configuratie-opties aan de fabrieksmethode toe te voegen.
Onderdelen van het ontwerppatroon van de fabrieksmethode
1. Schepper
Dit is een abstracte klasse of een interface die de fabrieksmethode declareert. De maker bevat doorgaans een methode die dient als fabriek voor het maken van objecten. Het kan ook andere methoden bevatten die met de gemaakte objecten werken.
2. Betonschepper
Concrete Creator-klassen zijn subklassen van de Creator die de fabrieksmethode implementeren om specifieke typen objecten te maken. Elke Concrete Creator is verantwoordelijk voor het creëren van een bepaald product.
rekha filmactrice
3. Product
Dit is de interface of abstracte klasse voor de objecten die de fabrieksmethode maakt. Het product definieert de gemeenschappelijke interface voor alle objecten die de fabrieksmethode kan creëren.
4. Betonproduct
Betonproductklassen zijn de daadwerkelijke objecten die door de fabrieksmethode worden gemaakt. Elke Concrete Product-klasse implementeert de Product-interface of breidt de Product-samenvattingsklasse uit.
Fabrieksmethode Ontwerppatroonvoorbeeld
Hieronder vindt u de probleemstelling om het Factory Method Design Pattern te begrijpen:
Overweeg een softwaretoepassing die de creatie van verschillende soorten voertuigen moet verwerken, zoals tweewielers, driewielers en vierwielers. Elk type voertuig heeft zijn eigen specifieke eigenschappen en gedrag.
1. Zonder fabrieksmethodeontwerppatroon
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(); } }> Uitvoer I am two wheeler>
Wat zijn de problemen met het bovenstaande ontwerp?
In het bovenstaande codeontwerp:
- Strakke koppeling: De klantenklasse
Client>instantiëert direct de concrete klassen (TwoWheeler>EnFourWheeler>) op basis van het invoertype dat tijdens de constructie is opgegeven. Dit leidt tot een nauwe koppeling tussen de klant en de concrete klassen, waardoor de code moeilijk te onderhouden en uit te breiden is. - Schending van het Single Responsibility Principle (SRP): De
Client>klasse is niet alleen verantwoordelijk voor het bepalen welk type voertuig moet worden geïnstantieerd op basis van het invoertype, maar ook voor het beheren van de levenscyclus van het voertuigobject (bijvoorbeeld opruimen). Dit is in strijd met het Single Responsibility Principle, dat stelt dat een klasse slechts één reden mag hebben om te veranderen. - Beperkte schaalbaarheid: Als u een nieuw type voertuig wilt toevoegen, moet u de
Client>klasse, die in strijd is met het open-gesloten principe. Dit ontwerp is niet schaalbaar omdat het geen nieuwe typen voertuigen kan huisvesten zonder de bestaande code te wijzigen.
Hoe vermijden we het probleem?
- Fabrieksinterface definiëren: Maak een
VehicleFactory>interface of abstracte klasse met een methode voor het maken van voertuigen. - Betonfabrieken implementeren: Betonfabrieksklassen implementeren (
TwoWheelerFactory>EnFourWheelerFactory>) die de implementatie uitvoerenVehicleFactory>interface en bieden methoden om exemplaren van specifieke typen voertuigen te creëren. - Refactor-klant: Wijzig de
Client>klasse om een te accepterenVehicleFactory>in plaats van voertuigen direct te instantiëren. De klant vraagt een voertuig aan bij de fabriek, waardoor er geen voorwaardelijke logica op basis van voertuigtypen nodig is. - Verbeterde flexibiliteit: Met deze aanpak is het toevoegen van nieuwe typen voertuigen net zo eenvoudig als het creëren van een nieuwe fabrieksklasse voor het nieuwe voertuigtype zonder de bestaande klantcode te wijzigen.
2. Met fabrieksmethode ontwerppatroon
Laten we de code opsplitsen in componentgewijze code:

1. Productinterface
Java // Product interface representing a vehicle public abstract class Vehicle { public abstract void printVehicle(); }> 2. Betonproducten
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. Creator-interface (fabrieksinterface)
Java // Factory interface defining the factory method public interface VehicleFactory { Vehicle createVehicle(); }> 4. Betonmakers (Betonfabrieken)
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(); } }> Volledige code van dit voorbeeld:
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(); } }> Uitvoer I am two wheeler I am four wheeler>
In de bovenstaande code:
Apple-emoji's op Android
-
Vehicle>fungeert als de productinterface en definieert de gemeenschappelijke methodeprintVehicle()>die alle concrete producten moeten implementeren. -
TwoWheeler>EnFourWheeler>zijn concrete productklassen die verschillende soorten voertuigen vertegenwoordigen en de implementatie ervan implementerenprintVehicle()>methode. -
VehicleFactory>fungeert als de Creator-interface (Factory Interface) met een methodecreateVehicle()>vertegenwoordigt de fabrieksmethode. -
TwoWheelerFactory>EnFourWheelerFactory>zijn concrete makersklassen (Betonfabrieken) die deVehicleFactory>interface om exemplaren van specifieke typen voertuigen te maken.
Gebruiksscenario's van het ontwerppatroon van de fabrieksmethode
Hier zijn enkele veelvoorkomende toepassingen van het Factory Method Design-patroon:
- Creatiekaders:
- JDBC (Java Database Connectivity) maakt veelvuldig gebruik van fabrieken voor het maken van verbindingen, instructies en resultatensets. Raamwerken voor afhankelijkheidsinjectie zoals Spring en Guice zijn sterk afhankelijk van fabrieken om bonen te creëren en te beheren.
- GUI-toolkits:
- Swing en JavaFX gebruiken fabrieken om UI-componenten zoals knoppen, tekstvelden en labels te creëren, waardoor maatwerk en flexibiliteit in het UI-ontwerp mogelijk zijn.
- Kaders voor logboekregistratie:
- Logboekframeworks zoals Log4j en Logback gebruiken fabrieken om loggers met verschillende configuraties te maken, waardoor controle over logniveaus en uitvoerbestemmingen mogelijk wordt.
- Serialisatie en deserialisatie:
- Objectserialisatieframeworks maken vaak gebruik van fabrieken om objecten te creëren op basis van geserialiseerde gegevens, waarbij verschillende serialisatieformaten en versiebeheer worden ondersteund.
- Plugin-systemen:
- Op plug-ins gebaseerde systemen maken vaak gebruik van fabrieken om plug-ins dynamisch te laden en te maken, waardoor uitbreidbaarheid en maatwerk mogelijk zijn.
- Spelontwikkeling:
- Game-engines gebruiken vaak fabrieken om verschillende soorten game-objecten, personages en niveaus te creëren, waardoor de code-organisatie en flexibiliteit worden bevorderd.
- Webontwikkeling:
- Webframeworks maken soms gebruik van fabrieken om weergavecomponenten, controllers en services te creëren, waardoor modulariteit en testbaarheid in webapplicaties mogelijk wordt.
Voordelen van het fabrieksmethodeontwerppatroon
De voordelen van het Factory Method Design Pattern zijn:
javafx-tutorial
- Ontkoppeling: Het scheidt de logica voor het maken van objecten van de clientcode die deze objecten gebruikt. Dit maakt de code flexibeler en onderhoudbaarder, omdat wijzigingen in het creatieproces geen aanpassingen aan de clientcode vereisen.
- Uitbreidbaarheid: Het is eenvoudig om nieuwe producttypen te introduceren zonder de klantcode te wijzigen. U hoeft alleen maar een nieuwe Concrete Creator-subklasse te maken en de fabrieksmethode te implementeren om het nieuwe product te produceren.
- Testbaarheid: Het vereenvoudigt het testen van eenheden doordat u tijdens tests de productcreatie kunt bespotten of uitsluiten. U kunt verschillende productimplementaties afzonderlijk testen zonder afhankelijk te zijn van de daadwerkelijke objectcreatie.
- Herbruikbaarheid van code: De fabrieksmethode kan worden hergebruikt in verschillende delen van de applicatie waar objectcreatie nodig is. Dit bevordert het centraliseren en hergebruiken van de logica voor het maken van objecten.
- Inkapseling: Het verbergt de concrete productklassen voor de klantcode, waardoor de code minder afhankelijk wordt van specifieke implementaties. Dit verbetert de onderhoudbaarheid en vermindert koppeling.
Nadelen van het ontwerppatroon van de fabrieksmethode
De nadelen van het Factory Method Design Pattern zijn:
- Verhoogde complexiteit: Het introduceert extra klassen en interfaces en voegt een abstractielaag toe die de code complexer kan maken om te begrijpen en te onderhouden, vooral voor degenen die niet bekend zijn met het patroon.
- Bovengronds: Het gebruik van polymorfisme en dynamische binding kan de prestaties enigszins beïnvloeden, hoewel dit in de meeste toepassingen vaak verwaarloosbaar is.
- Nauwe koppeling binnen producthiërarchieën: Concrete Creators zijn nog steeds nauw verbonden met hun bijbehorende betonproducten. Veranderingen in het ene vereisen vaak veranderingen in het andere.
- Afhankelijkheid van betonsubklassen: De clientcode is nog steeds afhankelijk van de abstracte Creator-klasse, waardoor kennis van de concrete subklassen ervan vereist is om correcte fabrieksmethode-aanroepen te kunnen doen.
- Potentieel voor overmatig gebruik: Het is belangrijk om het Factory Method-patroon oordeelkundig te gebruiken om over-engineering van de applicatie te voorkomen. Het eenvoudig maken van objecten kan vaak direct worden afgehandeld, zonder dat er een fabriek voor nodig is.
- Uitdagingen testen: Het testen van de fabriekslogica zelf kan complexer zijn.