팩토리 디자인 패턴이란?
팩토리(또는 팩토리 메서드) 디자인 패턴은 위임 및 캡슐화에 특화되어 있습니다. 이 패턴을 사용하면 슈퍼클래스가 인스턴스화를 서브클래스로 연기할 수 있습니다. 이는 기본 팩터리 메서드 패턴을 포함하는 클래스가 추상 클래스이기 때문입니다.
팩토리 메서드의 원래 버전은 생성할 제품을 모르기 때문에 구현되지 않은 메서드의 형태를 가정합니다. 팩토리 메소드는 자신이 어떤 제품을 만들고 있다는 것을 알 수 있지만, 자신이 만들 제품의 특정 특성은 알지 못합니다. 이 지식은 각 하위 클래스에서만 사용할 수 있습니다. 따라서 팩토리 메서드를 구현하고 적절한 개체를 만드는 책임은 전적으로 하위 클래스의 책임입니다.
자바로 팩토리 디자인 패턴 구현하기
이 문서에서는 샘플 피드백 보고서 생성 애플리케이션을 사용합니다. 이 응용 프로그램은 회사에서 받은 다양한 유형의 피드백(새 스낵에 대해)을 사용하여 특정 보고서를 생성합니다(팩토리 방법 사용). 따라서 팩토리 패턴은 다음 기본 제품 클래스를 기반으로 특정 피드백(또는 피드백 보고서)을 생성합니다.
public abstract class Feedback {
private String reviewerName;
private String reviewMessage;
private int reviewRatings;
public Feedback(String reviewerName, String reviewMessage, int reviewRatings) {
this.reviewerName = reviewerName;
this.reviewMessage = reviewMessage;
this.reviewRatings = reviewRatings;
}
public String getReviewerName() {
return reviewerName;
}
public void setReviewerName(String reviewerName) {
this.reviewerName = reviewerName;
}
public String getReviewMessage() {
return reviewMessage;
}
public void setReviewMessage(String reviewMessage) {
this.reviewMessage = reviewMessage;
}
public int getReviewRatings() {
return reviewRatings;
}
public void setReviewRatings(int reviewRatings) {
this.reviewRatings = reviewRatings;
}
}
모든 피드백에는 새 스낵에 대한 세 가지 필수 속성, 검토자 이름, 검토 메시지 및 숫자 등급(1에서 5까지)이 있습니다. 회사가 받게 될 다양한 유형의 피드백은 다음 세 가지 채널 중 하나에서 나옵니다.
이메일 피드백 수업
public class EmailFeedback extends Feedback {
private String reviewerEmail;
public EmailFeedback(String reviewerName, String reviewMessage, int reviewRatings, String reviewerEmail) {
super(reviewerName, reviewMessage, reviewRatings);
this.reviewerEmail = reviewerEmail;
}
public String getReviewerEmail() {
return reviewerEmail;
}
public void setReviewerEmail(String reviewerEmail) {
this.reviewerEmail = reviewerEmail;
}
}
메일 피드백 수업
public class MailFeedback extends Feedback {
private String returnAddress;
public MailFeedback(String reviewerName, String reviewMessage, int reviewRatings, String returnAddress) {
super(reviewerName, reviewMessage, reviewRatings);
this.returnAddress = returnAddress;
}
public String getReturnAddress() {
return returnAddress;
}
public void setReturnAddress(String returnAddress) {
this.returnAddress = returnAddress;
}
}
소셜 미디어 피드백 수업
public class SocialMediaFeedback extends Feedback {
private String reviewerHandle;
public SocialMediaFeedback(String reviewerName, String reviewMessage, int reviewRatings, String reviewerHandle) {
super(reviewerName, reviewMessage, reviewRatings);
this.reviewerHandle = reviewerHandle;
}
public String getReviewerHandle() {
return reviewerHandle;
}
public void setReviewerHandle(String reviewerHandle) {
this.reviewerHandle = reviewerHandle;
}
}
각 피드백 하위 클래스에는 고유한 속성이 있음을 알 수 있습니다. 즉, 해당 유형에 고유한 속성을 하나 이상 사용하여 각 피드백 유형에 대한 보고서를 만들어야 합니다.
단순한 공장
단순 팩토리는 팩토리 디자인 패턴을 사용하는 데 널리 사용되는 접근 방식입니다. 이 접근 방식은 방법(단순 공장)에서 모든 다양한 피드백(또는 제품)을 그룹화하고 매개 변수를 기반으로 적절한 피드백을 선택하는 것을 수반합니다.
public class FeedbackReportFactory {
public Feedback makeFeedback(String feedbackType) {
Feedback feedback = null;
if(feedbackType.equals("email")) {
feedback = new EmailFeedback();
}else if (feedbackType.equals("mail")) {
feedback = new MailFeedback();
}else if (feedbackType.equals("social")) {
feedback = new SocialMediaFeedback();
}
return feedback;
}
}
그러나 단순한 공장 접근 방식은 공장 디자인 패턴이 아니며 디자인 패턴도 아닙니다. 디자인 컨셉에 가깝습니다.
공장 방법
팩토리 방식은 디자인 패턴의 진정한 표현입니다. 팩터리 메서드를 사용하여 개편된 FeedbackReportFactory Java 클래스에는 이제 다음 코드가 포함됩니다.
public abstract class FeedbackReportFactory {
public abstract void makeFeedbackReport(Feedback feedback);
}
다음 클래스 다이어그램을 사용하여 팩토리 디자인 패턴의 구조를 정의할 수 있습니다.
위의 다이어그램에서 추상 클래스(또는 인터페이스)에 추상 버전의 팩터리 메서드가 포함되어 있음을 알 수 있습니다. 따라서 추상 클래스를 확장하는 구체적인 팩토리 클래스는 생성하려는 제품에 고유한 속성을 사용하여 팩토리 메서드를 구현합니다. 또한 구체적인 팩토리 클래스는 하나 이상의 제품을 생성해야 합니다.
샘플 애플리케이션에는 관련이 있지만 고유한 세 가지 제품이 있습니다. 각 피드백 유형에는 하나 이상의 고유 속성이 있습니다. 따라서 응용 프로그램에는 각 제품을 빌드하기 위해 세 개의 구체적인 공장이 있어야 합니다.
이메일 피드백 팩토리
public class EmailFeedbackReport extends FeedbackReportFactory{
EmailFeedback feedback;
@Override
public void makeFeedbackReport(Feedback feedback) {
this.feedback = (EmailFeedback) feedback;
System.out.println("\nReport For Feedback Via Email"+
"\nReviewer Name: " +this.feedback.getReviewerName() +
"\nFeedback: " + this.feedback.getReviewMessage() +
"\nRatings: " + this.feedback.getReviewRatings() +
"\nEmal Address: " + this.feedback.getReviewerEmail());
}
}
메일 피드백 팩토리
public class MailFeedbackReport extends FeedbackReportFactory {
MailFeedback feedback;
@Override
public void makeFeedbackReport(Feedback feedback) {
this.feedback = (MailFeedback) feedback;
System.out.println("\nReport For Feedback Via Mail"+
"\nReviewer Name: " +this.feedback.getReviewerName() +
"\nFeedback: " + this.feedback.getReviewMessage() +
"\nRatings: " + this.feedback.getReviewRatings() +
"\nMailing Address: " + this.feedback.getReturnAddress());
}
}
소셜 미디어 피드백 공장
public class SocialMediaFeedbackReport extends FeedbackReportFactory {
SocialMediaFeedback feedback;
@Override
public void makeFeedbackReport(Feedback feedback) {
this.feedback = (SocialMediaFeedback) feedback;
System.out.println("\nReport For Feedback Via Social Media"+
"\nReviewer Name: " + this.feedback.getReviewerName() +
"\nFeedback: " + this.feedback.getReviewMessage() +
"\nRatings: " + this.feedback.getReviewRatings() +
"\nReviewer Social Media Handle: " + this.feedback.getReviewerHandle());
}
}
샘플 애플리케이션 테스트
이제 각각의 팩토리 메서드를 사용하여 다양한 채널에서 받은 피드백에 대한 미니어처 보고서를 만들 수 있습니다. JUnit을 사용하여 애플리케이션을 테스트하거나 드라이버 클래스를 만들 수 있습니다.
public class Main {
public static void main(String[] args) {
Feedback feedback = new EmailFeedback("Nick", "Great product!", 5, "nick@email.com");
Feedback feedback2 = new MailFeedback("john", "The product is good but not something I would buy regularly", 4, "first Street");
Feedback feedback3 = new SocialMediaFeedback("Jane", "It's not for me", 2, "@janey");
FeedbackReportFactory factory = new EmailFeedbackReport();
FeedbackReportFactory factory2 = new MailFeedbackReport();
FeedbackReportFactory factory3 = new SocialMediaFeedbackReport();
factory.makeFeedbackReport(feedback);
factory2.makeFeedbackReport(feedback2);
factory3.makeFeedbackReport(feedback3);
}
위의 Main 클래스는 각 팩터리를 사용하여 3개의 보고서를 만들고 콘솔에 다음과 같은 출력을 생성합니다.
팩토리 디자인 패턴 사용의 이점
팩토리 디자인 패턴은 인터페이스(또는 추상 클래스)를 사용하여 구체적인 클래스를 만드는 디자인 유연성을 촉진합니다. 또한 응용 프로그램이 확장됨에 따라 새 클래스가 기존 인터페이스를 구현할 수 있도록 하여 다형성을 통해 확장성을 촉진합니다.
공장 설계 패턴을 사용할 때 두 가지 중요한 설계 원칙인 개방-폐쇄 및 IoC(Inversion of Control)를 활용하고 있습니다.
답글 남기기