본문 바로가기
C++ 200제/코딩 IT 정보

C# 팩토리 패턴 예제 (추상 Abstract Factory Method Pattern)

by vicddory 2017. 6. 6.

C# 팩토리 패턴 예제 (Abstract Factory Method Pattern)


C# 팩토리 패턴을 응용한 "연구실 기자재 관리 시스템 프로그램" 소스 코드입니다. 추상 팩토리 함수도 포함입니다.


첨부 파일


소스 1 - Factory Pattern.zip (팩터리 패턴 예제)

소스 2 - Abstract Factory Pattern.zip (추상 팩토리 패턴 예제)

소스 3 - Factory.zip (일반적인 패턴 예제)


문서 - DesignPattern_Term.hwp (관련 문서)


그리고 아래에 나오는 팩토리 패턴의 개요는 위에 나온 헤드 퍼스트의 디자인 패턴을 기반으로 작성되었습니다. 팩토리 패턴을 다루기 전, 짚고 넘어가야 할 부분이 있습니다.


1. NEW, 2. Interface


1번의 New는 구상 클래스의 인스턴스를 말하는 것인데, 구상 클래스가 뭘까요?

구상 클래스는 단순히 클래스 내부의 메소드들의 정의가 끝난 것을 말합니다. 말 그대로 실행 가능한 상태로서 모든 것이 갖추어진 클래스를 말하는 겁니다. 그러나, 이미 구현된 클래스를 이용한 객체 생성은 위험합니다.


프로그램은 클라이언트(학생이라면 학생 본인, 기업 입장이라면 고객)의 요구사항이 항상 변하기 때문에, 최소한의 수정으로 만족도를 높여줘야 하는데, 구상 클래스를 이용한 객체 생성은 유연하지 않고, 수정해야 할 곳이 많습니다.


반면, 2번의 Interface는 어떤 클래스든지 사용이 가능해서 매우 유연하므로, Interface를 이용하는 프로그래밍을 지향해야 합니다.


팩토리 패턴은, 팩토리Factory를 이용한 패턴Design Pattern을 의미합니다.


팩토리 메소드 패턴(Factory Method Pattern)

추상 팩토리 메소드 패턴(Abstract Factory Pattern)


팩토리를 이용한 패턴은 위의 두 가지 패턴으로 표현됩니다. 인용한 책에서도 가장 많은 분량을 차지하는 챕터이기도 하지요.


본론으로 들어가서, 팩토리는 = 객체 생성 처리 클래스를 의미합니다. 어떤 결과를 원하는 클라이언트를 위해 객체를 생성해 매개변수로써 객체의 성질을 정의합니다.


예를 들면, 아래와 같죠.


팩토리만 사용해선 팩토리 패턴이라 할 수는 없다[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


문제는 팩토리만 사용해선 팩토리 패턴이라 할 수 없다는 점입니다. Factory Pattern 팩토리 메소드 패턴에서는,


1. 객체를 생성하기 위한 Interface 정의함

2. 생산자 클래스는 서브 클래스로 인해 성질이 정의됨

3. 제품 클래스는 실제 제품을 제작 - 팩토리에서 객체 생성


이런 과정의 산출물을 예상해 봅니다.


결과는아래의 그림과 같습니다.


팩토리 역할 - 인스턴스 생성[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


생산자 클래스와 제품 클래스[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


팩토리 메소드 패턴의 장점은,


- 제품 생산, 사용 부분 분리 가능

- 제품의 추가나 구성의 변화에도 느슨하게 결합되어 유연함

- 객체 생성 코드는 오직 하나의 객체나 메소드가 담당

- 이로 인해 중복을 방지할 수 있고 변화 시엔 해당하는 구상 클래스만 조금 손봐주면 됩니다.

그렇지만, 세상에 완벽한 100%는 없듯이, New를 통한 구상 클래스의 객체 생성은 절대로 피할 수 없습니다. Factory Pattern 이것을 좀 더 완화해주기 위한 방법의 하나가 바로 의존성 뒤집기 원칙(Dependency Inversion Principle)입니다.


여기까지가 팩토리 메소드 패턴이고, 여기서 좀 더 디테일한 패턴 공부를 위해선 추상 팩토리 메소드 패턴을 다뤄야 합니다. 책에 나온 예제처럼 계속해서 피자 얘기를 하자면, 이런 문제가 다음에 발생합니다.


시카고 피자 메뉴 - 뉴욕 피자 메뉴[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


같은 피자인데도 재료가 다릅니다.


이런 문제의 해결책으론, 원재료를 생산할 팩토리 인터페이스를 생성해 재료별 생성 메소드를 정의하되, 공통으로 사용되는 부분은 추상 클래스로 분리하는 것입니다.


추상 팩토리 패턴을 이용하면, 인터페이스를 이용해 연관되거나 의존하는 객체를 구상 클래스를 별도로 지정하지 않고도 생성할 수 있습니다. 예를 들면 아래와 같이 Factory Pattern 코딩할 수 있죠.


원재료 생산을 위한 팩토리 - 뉴욕의 원재료 공장[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


생산되는 부분은 이미 별도로 존재하고 제품을 정의하는 부분도 이처럼 별도로 존재합니다. 다이어그램으로 다시 살펴보죠.


추상 팩토리 패턴 다이어그램[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


지금까지 살펴본, 팩토리 패턴은 팩토리 메소드 패턴과, 추상 팩토리 메소드로서 두 개가 존재하는데, 그 차이는 이렇습니다.


1. 특정 구현(구상 클래스)으로부터 분리된 제품 생성

팩토리 메소드 - 추상화된 클래스를 사용

추상 팩토리 - 객체 사용

2. 클라이언트와 구상 형식을 분리

팩토리 메소드

- 팩토리 메소드를 서브 클래스에서 오버라이드(첨부된 코드에서도 오버라이드 된 부분을 유심히 보세요)

- Factory Pattern 클라이언트(사용자)는 사용할 추상 형식만 알면 됨

- 추상 팩토리 - 제품군을 만들기 위한 추상 형식(인터페이스) 제공(제품이 아니라 제품군입니다)


3. 수정의 필요성

팩토리 메소드 - 한 가지 제품만 생산하기에 하나의 메소드가 필요

추상 팩토리 - 제품군(family)을 생성하기에 인터페이스도 큰 편, 제품이 추가되면 인터페이스의 수정이 필요


다시 한번 정리된 그림을 살펴보도록 하죠.


팩토리 메소드 패턴과 추상 팩토리 패턴 1[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


팩토리 메소드 패턴과 추상 팩토리 패턴 2[C# 디자인 패턴] 컴퓨터 프로그래밍 기초 강좌


마지막으로 정리해 보겠습니다.


◎ 팩토리

→ 객체 생성을 캡슐화

→ 구상 클래스가 아닌, 추상 클래스와 인터페이스에 맞춰 코딩이 가능

→ 패턴은 아니지만, 클라이언트와 구상 클래스를 분리하는 데 활용 가능


◎ 추상 팩토리 패턴

→ 객체 구성을 활용 (Factory Pattern 제품군)

→ 구상 클래스에 의존하지 않고 관련된 객체들로 이루어진 제품군을만듬


◎ 팩토리 메소드 패턴

→ 상속을 활용해 객체 생성을 서브 클래스에 위임

→ 서브 클래스는 팩토리메소드를구현해 객체를 생성


◎ 팩토리 패턴 공통

→ 구상 클래스에 대한 의존성을 줄임(느슨한 결합, 유연한 프로그래밍)


◎ 의존성 뒤집기 원칙

→ 구상 클래스의 의존성을 줄이고 추상화 지향이 가능


C# 팩토리 패턴 예제 (Abstract Factory Method Pattern)

댓글