[Design Pattern] 팩토리 메소드 패턴

Factory Method Pattern

팩토리 메소드 패턴이란 객체를 생성하기 위해 인터페이스를 정의하지만 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브클래스가 내리도록 하는 패턴이다.

활용성

  1. 어떤 클래스가 자신이 생성해야 하는 객체의 클래스를 예측할 수 없을 때
  2. 생성할 객체를 기술하는 책임을 자신의 서브클래스가 지정했으면 할 때
  3. 객체 생성의 책임을 몇 개의 보조 서브클래스 가운데 하나에게 위임하고 어떤 서브클래스가 위임자인지에 대한 정보를 국소화시키고 싶을 때

팩토리 메소드 패턴 사용에 따른 결과

서브클래스에 대한 hook 메소드 제공

팩토리 메소드로 클래스 내부에서 객체를 생성하는 것이 객체를 직접 생성하는 것보다 응용성이 높아진다.

병렬적인 클래스 계통 연결

Creator 클래스만이 팩토리 메소드를 호출한다. 이 장점 뿐만 아니라 병렬적 클래스 계통은 클래스가 자신의 책임을 분리된 다른 클래스에 위임할 때 발생한다. 팩토리 메소드 패턴을 이용하면 이와 같은 구현이 가능해진다.

추상 팩토리 패턴과의 차이

추상 팩토리는 객체를 생성하는 오브젝트 클래스를 팩토리화 시킨 것이고 팩토리 메소드는 객체를 생성하는 방법을 팩토리화 시킨 것이다.

팩토리 메소드

구조

팩토리 매소드의 구조는 다음과 같다.

Factory Method Pattern Diagram

C++ 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void FactoryMethodPattern()
{
callPdfDocument();
callWordDocument();
}

void callPdfDocument()
{
DocumentCreator* creator = new PDFDocumentCreator();
Document* document = creator->create();
document->context();
creator->close(document);
}

void callWordDocument()
{
DocumentCreator* creator = new WordDocumentCreator();
Document* document = creator->create();
document->context();
creator->close(document);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class DocumentCreator
{
public:
virtual ~DocumentCreator() {};
virtual Document* create() = 0;
void close(Document* document)
{
delete document;
}
};

class PDFDocumentCreator : public DocumentCreator
{
public:
~PDFDocumentCreator() override {};

Document* create() override
{
return new PDFDocument();
}
};

class WordDocumentCreator : public DocumentCreator
{
public:
~WordDocumentCreator() override {};

Document* create() override
{
return new WordDocument();
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Document
{
public:
virtual ~Document() {};
virtual void context() = 0;
};

class PDFDocument : public Document
{
public:
~PDFDocument() override
{
std::cout<<"PDF Document close"<<std::endl;
};

void context() override
{
std::cout<<"PDF Document"<<std::endl;
}
};

class WordDocument : public Document
{
public:
~WordDocument() override
{
std::cout<<"Word Document close"<<std::endl;
};

void context() override
{
std::cout<<"Word Document"<<std::endl;
}
};

java 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Client {
public static void main(String[] args) {
callDocument(new PdfDocumentCreator());
callDocument(new WordDocumentCreator());
}

public static void callDocument(DocumentCreator documentCreator) {
DocumentCreator creator = documentCreator;
Document document = creator.create();
document.Context();
creator.close(document);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface DocumentCreator {
Document create();

default void close(Document document) {
document.Close();
}
}

public class PdfDocumentCreator implements DocumentCreator{
public Document create() {
return new PdfDocument();
}
}

public class WordDocumentCreator implements DocumentCreator{
public Document create() {
return new WordDocument();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public interface Document {
void Context();
void Close();
}

public class PdfDocument implements Document{
public PdfDocument() {
System.out.println("Pdf Document Create");
}

public void Context() {
System.out.println("Pdf Document Context");
}

public void Close() {
System.out.println("Pdf Document Close");
}
}

public class WordDocument implements Document{
public WordDocument() {
System.out.println("Word Document Create");
}

public void Context() {
System.out.println("Word Document Context");
}

public void Close() {
System.out.println("Word Document Close");
}
}
Author: Song Hayoung
Link: https://songhayoung.github.io/2020/08/11/Design%20Pattern/FactoryMethodPattern/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.