Factory Method Pattern VS Strategy Pattern
Strategy Pattern을 어떻게 대안이 될 수 있는가? ^^
- Factory Method pattern Diagram
class FLEX :Equipment
{
public override void Start()
{
//VK93과 같은 일을 한다(중복코드 발생)
//do someting V93K about start
}
public override void Load()
{
//CATALIST와 같은 일을 한다(중복코드 발생)
//do someting CATALIST about load
}
public override void Modify()
{
//do someting FLEX about modify
}
}
문제점 : VK93의 Start() or Catalist 의 Load() 함수가 변경된다면 같이 수정이 필요
class D10 : Equipment
{
public override void Start()
{
//do someting D10 about load
}
public override void Load()
{
//do someting D10 about load
}
//LSP(서브타입은 언제나 자신이 기반타입으로 교체할 수 있어야 한다) 위반
public override void Modify()
{
throw new NotImplementedException();
}
}
public partial class Form1 : Form
{
EquipmentCommander _ec = new EquipmentCommander();
public Form1()
{
InitializeComponent();
Equipment vk93 = EquipmentFactory.CreateEquipment("V93K");
Equipment Catalist = EquipmentFactory.CreateEquipment("Catalist");
Equipment D10 = EquipmentFactory.CreateEquipment("D10");
Equipment Flex = EquipmentFactory.CreateEquipment("FLEX");
_ec.Excute(vk93);
_ec.Excute(Catalist);
_ec.Excute(Flex);
//서브클래스 인스턴스를 파라미터로 전달 했을 때 메소드가 이상하게 작동
//Modify function이 제대로 구현되지 않음
_ec.Excute(D10);
}
}
문제점 : LSP를 위반한다. 즉 기반 클래스로 서브클래스의 사용을 하지 못한다.
- Strategy Pattern Diagram
public class Equipment
{
public int ID { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public string PropertyforManager { get; set; }
//각각 Strategy 를 가지고 있다.
public IStart start { get; set; }
public IModify modify { get; set; }
public ILoad load { get; set; }
}
Factory 에서 생성 시에 맞는 전략을 구현한다.
class EquipmentFactory
{
public static Equipment CreateEquipment(string EqpName)
{
Equipment eqp = new Equipment();
eqp.Name = EqpName;
if (EqpName.Equals("V93K"))
{
eqp.start = new StartV93K();
eqp.load = new LoadV93K();
eqp.modify = new ModifyV93K();
}
else if (EqpName.Equals("Catalist"))
{
eqp.start = new StartCatalist();
eqp.load = new LoadCatalist();
eqp.modify = new ModifyCatalist();
}
else if (EqpName.Equals("D10"))
{
eqp.start = new StartD10();
eqp.load = new LoadD10 ();
//modify 가 필요없는 Equipment는 ModifyNothing을 구현한다.
eqp.modify = new ModifyNothing();
}
else if (EqpName.Equals("FLEX"))
{
// Flex는 V93의 Start와 Catalist의 Load를 구현함으로 중복 코드의 없음
eqp.start = new StartV93K();
eqp.load = new LoadCatalist();
eqp.modify = new ModifyFlex();
}
else
{
throw new Exception("unregisted Eqp Class");
}
return eqp;
}
}
문제점 해결 : 전략 객체를 이용해서 장비가 행위를 한다.
중복코드를 만들지 않는다.(수정이 필요하면 전략객체만을 수정하면 된다.)
새로운 행위가 필요하면 기반 클래스의 수정없이 전략 클래스를 확장(OCP를 지킴)
public partial class Form1 : Form
{
EquipmentCommander _ec = new EquipmentCommander();
public Form1()
{
InitializeComponent();
Equipment vk93 = EquipmentFactory.CreateEquipment("V93K");
Equipment Catalist = EquipmentFactory.CreateEquipment("Catalist");
Equipment D10 = EquipmentFactory.CreateEquipment("D10");
Equipment Flex = EquipmentFactory.CreateEquipment("FLEX");
_ec.Excute(vk93);
_ec.Excute(Catalist);
_ec.Excute(Flex);
//D10은 modify를 하지 않지만 ModifyNothing()을 구현해서 문제를 해결한다.
=> Equipment Generator Code
else if (EqpName.Equals("D10"))
{
eqp.start = new StartD10();
eqp.load = new LoadD10 ();
eqp.modify = new ModifyNothing();
}
_ec.Excute(D10);
//Flex장비의 행동을vk93과 같게 변경하고 싶다면??
//클래스를 생성해서 위임해야 겠지만 예제 이므로 여기서 테스트 하였음
Flex.start = new StartV93K();
Flex.load = new LoadV93K();
Flex.modify = new ModifyV93K();
_ec.Excute(Flex);
}
}
문제점 해결 : EquipmentCommander 의 Execute가 기반 타입으로 작동하는데 문제가 없다
즉 LSP를 위반하지 않는다 ^^