팩토리 패턴 정의
팩토리 패턴의 핵심 : new 예약어를 패턴에 사용한 서브 클래스나, 인터페이스를 상속한 클래스에게 넘기는 방법이다.
1. 팩토리 메서드 패턴
클래스의 인스턴스 생성을 서브 클래스에게 결정시키는 방법이다. (서브클래스를 이용한 방법)
2. 추상 팩토리 패턴 (클래스 다이어그램 까지만 포스팅)
인터페이스를 상속한 클래스에게 인스턴스 생성을 시키는 방법이다. (인터페이스를 이용한 방법)
필요한 상황
1. new 예약어를 최대한 인계하는 코드가 필요할 때 -> new 예약어는 변화가 힘든 프로그램을 만들기 때문
switch(instanceName)
{
case "1":
return new InstanceOne();
case "2":
return new InstanceTwo();
case "3":
return new InstanceThree();
...
}
향후 코드 수정이 무조건 필요한 팩토리 함수..
2. 인스턴스 생성 함수가 필요하고, 인스턴스의 종류는 가변인 경우
3. 카테고리화한 비즈니스 모델에 대한 인스턴스 생성을 체계화하고 싶은 경우
Class 다이어그램
1. 팩토리 메서드 패턴
2. 추상 팩토리 패턴
코드
1. BuisnessModel class
public abstract class BuisnessModel
{
public string Name { get; set; }
public int Number { get; set; }
public abstract void doSomething1();
public abstract void doSomething2();
public override string ToString()
{
return $"{Name} : {Number}";
}
}
2. BuisnessModel class의 sub class들 (팩토리에서 생성할 다양한 모델)
public class FactoryMethodPattern_SubOne_BuisnessOneModel : BuisnessModel
{
public override void doSomething1()
{
Console.WriteLine($"do FactoryMethodPattern_SubOne_BuisnessOneModel job 1");
}
public override void doSomething2()
{
Console.WriteLine($"do FactoryMethodPattern_SubOne_BuisnessOneModel job 2");
}
}
public class FactoryMethodPattern_SubOne_BuisnessTwoModel : BuisnessModel
{
public override void doSomething1()
{
Console.WriteLine($"do FactoryMethodPattern_SubOne_BuisnessOneModel job 1");
}
public override void doSomething2()
{
Console.WriteLine($"do FactoryMethodPattern_SubOne_BuisnessTwoModel job 2");
}
}
public class FactoryMethodPattern_SubTwo_BuisnessOneModel : BuisnessModel
{
public override void doSomething1()
{
Console.WriteLine($"do FactoryMethodPattern_SubTwo_BuisnessOneModel job 1");
}
public override void doSomething2()
{
Console.WriteLine($"do FactoryMethodPattern_SubTwo_BuisnessOneModel job 2");
}
}
public class FactoryMethodPattern_SubTwo_BuisnessTwoModel : BuisnessModel
{
public override void doSomething1()
{
Console.WriteLine($"do FactoryMethodPattern_SubTwo_BuisnessOneModel job 1");
}
public override void doSomething2()
{
Console.WriteLine($"do FactoryMethodPattern_SubTwo_BuisnessTwoModel job 2");
}
}
3. InstanceStore 추상 Class
public abstract class BaseInstanceStore
{
public BuisnessModel GetBuisnessModel(string buisness_type)
{
BuisnessModel bm = OrderBuisnessModel(buisness_type);
bm.doSomething1();
bm.doSomething2();
return bm;
}
protected abstract BuisnessModel OrderBuisnessModel(string buisness_type);
}
4. SubInstanceStore Class 들
public class SubOneInstanceStore : BaseInstanceStore
{
protected override BuisnessModel OrderBuisnessModel(string buisness_type)
{
switch(buisness_type)
{
case "ONE":
return new FactoryMethodPattern_SubOne_BuisnessOneModel() { Name = "FactoryMethodPattern_SubOne_BuisnessOneModel of SubOneInstanceStore", Number = 0 };
case "TWO":
return new FactoryMethodPattern_SubOne_BuisnessTwoModel() { Name = "FactoryMethodPattern_SubOne_BuisnessTwoModel of SubOneInstanceStore", Number = 0 };
default:
return new FactoryMethodPattern_SubOne_BuisnessOneModel() { Name = "FactoryMethodPattern_SubOne_BuisnessOneModel of SubOneInstanceStore", Number = 0 };
}
}
}
public class SubTwoInstanceStore : BaseInstanceStore
{
protected override BuisnessModel OrderBuisnessModel(string buisness_type)
{
switch(buisness_type)
{
case "ONE":
return new FactoryMethodPattern_SubTwo_BuisnessOneModel() { Name = "FactoryMethodPattern_SubTwo_BuisnessOneModel of SubOneInstanceStore", Number = 0 };
case "TWO":
return new FactoryMethodPattern_SubTwo_BuisnessTwoModel() { Name = "FactoryMethodPattern_SubTwo_BuisnessTwoModel of SubOneInstanceStore", Number = 0 };
default:
return new FactoryMethodPattern_SubTwo_BuisnessOneModel() { Name = "FactoryMethodPattern_SubTwo_BuisnessOneModel of SubOneInstanceStore", Number = 0 };
}
}
}
5. Main 코드
BaseInstanceStore instanceOneFactory = new SubOneInstanceStore();
BuisnessModel bm1 = instanceOneFactory.GetBuisnessModel("ONE");
Console.WriteLine(bm1.ToString());
BaseInstanceStore instanceTwoFactory = new SubTwoInstanceStore();
BuisnessModel bm2 = instanceTwoFactory.GetBuisnessModel("TWO");
Console.WriteLine(bm2.ToString());
코드 설명
1. BuisnessModel Class는 우리가 new 예약어를 통해 실제 인스턴스를 생성할 Class이다. 향후 다양한 파생 클래스의 베이스 클래스로 이용할 것이다.
2. BuisnessModel class의 sub class들이다. 다양한 모델로 추가 삭제 가능하다.
3. InstanceStore 추상 Class이다. 파생 클래스로 BuisnessModel을 첫 번째로 대분류 한다.
4. InstanceStore의 파생 클래스이다. 파생 클래스로 BuisnessModel을 대분류 하고 파생 클래스의 함수를 통해 소분류로 BuisnessModel을 나눈다.
5. Main 코드는 팩토리 메서드 패턴을 사용하는 방법이다.
-- 추상 팩토리 패턴은 생략-- (팩토리 메소드 패턴을 많이 이용하기 때문..)
설명 보충을 위한 그림 자료
필요에 따라 추가 설명
1. 팩토리 패턴은 우리가 정의한 비즈니스 모델이 많을수록 빛을 발한다.
2. 비즈니스 모델이 추가될 경우 수정해야 하는 부분은 대분류 한 InstanceFactory의 내부 함수이다.
정리 및 결론
단순 팩토리 함수(switch문으로 만든)와 팩토리 패턴을 비교했을 때 비즈니스 모델의 추가 삭제 요인이 적다면 단순 팩토리 함수가 유용해 보인다. 따라서 우리는 단순 팩토리 함수와 팩토리 패턴을 구분하고 장단점을 따지고 구현할지 말지 판단해야 한다.
코더가 아닌 개발자가 되자!!
'Program > SW Design Patterns' 카테고리의 다른 글
CH6 커맨드 패턴 (0) | 2023.03.07 |
---|---|
CH5 데코레이터 패턴 (1) | 2023.03.05 |
CH3 옵저버 패턴 (0) | 2023.03.03 |
CH2 싱글턴 패턴 (0) | 2023.03.02 |
CH1 전략 패턴 (0) | 2023.03.02 |