Het ontwerppatroon van de fabriek (of fabrieksmethode) is gespecialiseerd in delegatie en inkapseling. Met dit patroon kan een superklasse de instantiëring naar subklassen uitstellen. Dit komt omdat de klasse die het patroon van de primaire fabrieksmethode bevat, abstract is.
De oorspronkelijke versie van de fabrieksmethode neemt de vorm aan van een niet-geïmplementeerde methode omdat het product dat het zal maken niet bekend is. De fabrieksmethode weet misschien dat het een product aan het maken is, maar kent niet de specifieke kenmerken van het product dat het gaat maken. Deze kennis is alleen beschikbaar voor de respectievelijke subklassen. Daarom is de verantwoordelijkheid voor het implementeren van de fabrieksmethode en het maken van geschikte objecten uitsluitend die van een subklasse.
Implementatie van het Factory Design Pattern in Java
Dit artikel maakt gebruik van een voorbeeldtoepassing voor het genereren van feedbackrapporten. Deze applicatie gebruikt de verschillende soorten feedback die een bedrijf ontvangt (voor een nieuwe snack) om specifieke rapporten te maken (volgens de fabrieksmethode). Daarom zal het fabriekspatroon specifieke feedback (of feedbackrapport) creëren, waarbij de volgende primaire productklasse als basis wordt gebruikt:
openbaarabstractklasFeedback{
privaat Snaar reviewerNaam;
privaat Snaar beoordelingBericht;
privaatint beoordelingBeoordelingen;
openbaarFeedback(String reviewerName, String reviewMessage, int beoordelingBeoordelingen){
dit.reviewerName = reviewerName;
dit.reviewMessage = reviewMessage;
dit.reviewRatings = reviewRatings;
}
openbaar Snaar getReviewerName(){
opbrengst reviewerNaam;
}
openbaarleegtesetReviewerName(String reviewerName){
dit.reviewerName = reviewerName;
}
openbaar Snaar getReviewMessage(){
opbrengst beoordelingBericht;
}
openbaarleegtesetReviewMessage(String reviewMessage){
dit.reviewMessage = reviewMessage;
}
openbaarintkrijgReviewRatings(){
opbrengst beoordelingBeoordelingen;
}
openbaarleegtesetReviewRatings(int beoordelingBeoordelingen){
dit.reviewRatings = reviewRatings;
}
}
Elke feedback heeft drie verplichte eigenschappen, een reviewernaam, een reviewbericht en een cijferwaardering (van één tot vijf) voor de nieuwe snack. De verschillende soorten feedback die het bedrijf zal ontvangen, zijn afkomstig van een van de volgende drie kanalen:
Feedbackklasse per e-mail
openbaarklasE-mailFeedbackstrekt zich uitFeedback{
privaat Snaar recensentE-mail;
openbare e-mailfeedback(Snaar reviewerName, Snaar beoordelingBericht, int beoordelingBeoordelingen, Snaar reviewerE-mail) {
super(reviewerName, reviewMessage, reviewRatings);
dit.reviewerEmail = reviewerEmail;
}
openbaar Snaar getReviewerEmail(){
opbrengst recensentE-mail;
}
openbaarleegtesetReviewerEmail(String reviewerE-mail){
dit.reviewerEmail = reviewerEmail;
}
}
Mail Feedback-klasse
openbaarklasMailFeedbackstrekt zich uitFeedback{
privaat Snaar retouradres;
openbare e-mailfeedback(Snaar reviewerName, Snaar beoordelingBericht, int beoordelingBeoordelingen, Snaar retouradres) {
super(reviewerName, reviewMessage, reviewRatings);
dit.returnAddress = retouradres;
}openbaar Snaar getReturnAddress(){
opbrengst retouradres;
}
openbaarleegtesetReturnAddress(Tekenreeks returnAddress){
dit.returnAddress = retouradres;
}
}
Feedbackklasse sociale media
openbaarklasFeedback op sociale mediastrekt zich uitFeedback{
privaat Snaar recensentHandle;
openbare SocialMediaFeedback(Snaar reviewerName, Snaar beoordelingBericht, int beoordelingBeoordelingen, Snaar reviewerHandle) {
super(reviewerName, reviewMessage, reviewRatings);
dit.reviewerHandle = reviewerHandle;
}
openbaar Snaar getReviewerHandle(){
opbrengst recensentHandle;
}
openbaarleegtesetReviewerHandle(String reviewerHandle){
dit.reviewerHandle = reviewerHandle;
}
}
U zult merken dat elke feedbacksubklasse een unieke eigenschap heeft. Dit betekent dat u het rapport voor elk feedbacktype moet maken met ten minste één eigenschap die uniek is voor dat type.
De eenvoudige fabriek
Een eenvoudige fabriek is een populaire benadering van het gebruik van het fabrieksontwerppatroon. Deze aanpak omvat het groeperen van alle verschillende terugkoppelingen (of producten) in een methode (de eenvoudige fabriek) en het selecteren van de juiste terugkoppeling op basis van een parameter.
openbaarklasFeedbackReportFactory{
openbaar Feedback maakFeedback(TekenreeksfeedbackType){
Terugkoppeling terugkoppeling = nul;
als(feedbackType.equals("e-mail")) {
feedback = nieuw E-mailFeedback();
}andersals (feedbackType.equals("mail")) {
feedback = nieuw MailFeedback();
}andersals (feedbackType.equals("sociaal")) {
feedback = nieuw Feedback op sociale media();
}
opbrengst feedback;
}
}
De eenvoudige fabrieksbenadering is echter niet het fabrieksontwerppatroon en ook geen ontwerppatroon. Het is meer een ontwerpconcept.
De fabrieksmethode
De fabrieksmethode is de waarheidsgetrouwe weergave van het ontwerppatroon. Met behulp van de fabrieksmethode, de hervormde FeedbackReportFactoryJava-klasse zal nu de volgende code bevatten:
openbaarabstractklasFeedbackReportFactory{
openbaarabstractleegtemaakFeedbackReport(Feedback);
}
U kunt de structuur van het fabrieksontwerppatroon definiëren met het volgende klassendiagram:
In het bovenstaande diagram ziet u dat een abstracte klasse (of interface) een abstracte versie van de fabrieksmethode zal bevatten. De concrete fabrieksklassen die de abstracte klasse uitbreiden, zullen dus de fabrieksmethode implementeren, gebruikmakend van eigenschappen die uniek zijn voor het product dat het wil maken. Houd er ook rekening mee dat elke concrete fabrieksklasse een of meer producten moet maken.
De voorbeeldtoepassing heeft drie gerelateerde maar unieke producten. Elk feedbacktype heeft ten minste één unieke eigenschap. De applicatie heeft dus drie betonfabrieken nodig om elk product te bouwen.
E-mail feedbackfabriek
openbaarklasE-mailFeedbackReportstrekt zich uitFeedbackReportFactory{
E-mailFeedbackfeedback;
@Overschrijven
openbaarleegtemaakFeedbackReport(Feedback){
dit.feedback = (EmailFeedback) feedback;
Systeem.uit.println("\nRapportVoorFeedbackViaE-mail" +
"\nReviewer Naam: " +dit.feedback.getReviewerName() +
"\nFeedback: " + dit.feedback.getReviewMessage() +
"\nBeoordelingen: " + dit.feedback.getReviewRatings() +
"\nEmal adres: " + dit.feedback.getReviewerEmail());
}
}
Mail Feedback Fabriek
openbaarklasMailFeedbackReportstrekt zich uitFeedbackReportFactory{
MailFeedback-feedback;
@Overschrijven
openbaarleegtemaakFeedbackReport(Feedback){
dit.feedback = (MailFeedback) feedback;
Systeem.uit.println("\nRapportVoorFeedbackViaMail" +
"\nReviewer Naam: " +dit.feedback.getReviewerName() +
"\nFeedback: " + dit.feedback.getReviewMessage() +
"\nBeoordelingen: " + dit.feedback.getReviewRatings() +
"\nMailadres: " + dit.feedback.getReturnAddress());
}
}
Feedbackfabriek op sociale media
openbaarklasSocialMediaFeedbackReportstrekt zich uitFeedbackReportFactory{
SocialMediaFeedback-feedback;
@Overschrijven
openbaarleegtemaakFeedbackReport(Feedback){
dit.feedback = (SocialMediaFeedback)feedback;
Systeem.uit.println("\nRapportVoorFeedbackViaSociaalMedia" +
"\nReviewer Naam: " + dit.feedback.getReviewerName() +
"\nFeedback: " + dit.feedback.getReviewMessage() +
"\nBeoordelingen: " + dit.feedback.getReviewRatings() +
"\nBeoordelaar Social Media-handvat: " + dit.feedback.getReviewerHandle());
}
}
De voorbeeldtoepassing testen
Nu kunt u de respectieve fabrieksmethoden gebruiken om miniatuurrapporten te maken over de feedback die u van de verschillende kanalen ontvangt. Jij kan test de applicatie met behulp van JUnit, of u kunt een stuurprogrammaklasse maken:
openbaarklasVoornaamst{
openbaarstatischleegtevoornaamst(String[] argumenten){
Terugkoppeling terugkoppeling = nieuw E-mailFeedback("Nick", "Geweldig product!", 5, "[email protected]");
Terugkoppeling terugkoppeling2 = nieuw E-mailFeedback("John", "Het product is goed, maar niet iets dat ik regelmatig zou kopen", 4, "eerste straat");
Terugkoppeling terugkoppeling3 = nieuw Feedback op sociale media("Jane", "Het is niet voor mij", 2, "@janey");
FeedbackReportFabriek fabriek = nieuw E-mailFeedbackReport();
FeedbackRapportFabriek fabriek2 = nieuw MailFeedbackRapport();
FeedbackRapportFabriek fabriek3 = nieuw SocialMediaFeedbackRapport();
fabriek.makeFeedbackReport(feedback);
fabriek2.makeFeedbackReport(feedback2);
fabriek3.makeFeedbackReport(feedback3);
}
De klasse Main hierboven gebruikt de respectievelijke fabrieken om drie rapporten te maken, met de volgende uitvoer in de console:
Voordelen van het gebruik van het fabrieksontwerppatroon
Het fabrieksontwerppatroon bevordert ontwerpflexibiliteit, waarbij u interfaces (of abstracte klassen) gebruikt om concrete klassen te maken. Het bevordert ook de schaalbaarheid door polymorfisme, door nieuwe klassen toe te staan de bestaande interface te implementeren naarmate de toepassing uitbreidt.
Wanneer u het fabrieksontwerppatroon gebruikt, gebruikt u twee belangrijke ontwerpprincipes: Open-gesloten en Inversion of Control (IoC).