💡 서로 관련있는 객체들을 묶어서 팩토리를 만들고, 이 팩토리들을 조건에 따라 생성하도록 다시 팩토리를 만들어서 객체를 생성하는 패턴
예시를 들자면, 컴퓨터를 만들 때, 마우스, 키보드가 필요합니다. 그리고 그 제조사들로 삼성과 lg가 있다고 해봅시다. 하나의 컴퓨터는 당연하게 하나의 제조사로 이루어져야합니다
어제 공부했던 팩토리메서드 패턴을 이용해서 이 상황을 해결해봅시다.
일단 Lg, 삼성 키보드 클래스를 만들고 Keyboard 인터페이스를 정의합니다. 그리고 입력된 조건에 따라 구현체를 만들어주는 KeyboardFactory를 만들어줍니다.
public interface Keyboard {
}
public class SamsungKeyboard implements Keyboard {
public SamsungKeyboard() {
System.out .println("SamsungKeyboard" );
}
}
public class LgKeyboard implements Keyboard {
public LgKeyboard() {
System.out .println("LgKeyboard" );
}
}
public class KeyboardFactory {
public Keyboard makeKeyboard (String brand) {
Keyboard keyboard = null;
switch (brand) {
case "Samsung" :
keyboard = new SamsungKeyboard ();
break ;
case "Lg" :
keyboard = new LgKeyboard ();
break ;
}
return keyboard;
}
}
같은 방식으로 마우스도 만들어봅시다.
public interface Mouse {
}
public class SamsungMouse implements Mouse {
public SamsungMouse() {
System.out .println("SamsungMouse" );
}
}
public class LgMouse implements Mouse {
public LgMouse() {
System.out .println("LgMouse" );
}
}
public class MouseFactory {
public Mouse makeMouse (String brand) {
Mouse Mouse = null;
switch (brand) {
case "Samsung" :
Mouse = new SamsungMouse ();
break ;
case "Lg" :
Mouse = new LgMouse ();
break ;
}
return Mouse ;
}
}
이제 ComputerFactory 를 만들어서 그곳에서 컴퓨터를 만들어줘야합니다.
public class ComputerFactory {
public void makeComputer(String brand ) {
KeyboardFactory keyboardFactory = new KeyboardFactory() ;
MouseFactory mouseFactory = new MouseFactory() ;
keyboardFactory.makeKeyboard(brand ) ;
mouseFactory.makeMouse(brand ) ;
}
}
이렇게 했을 시에 문제점이 있습니다. 컴퓨터의 구성품이 현재는 마우스, 키보드 뿐이지만 추가로 모니터, 스피커 등이 추가된다고 생각해봅시다. 그러면 MonitorFactory, SpeakerFactory 가 추가로 생성되고 ComputerFactory에도 추가로 코드를 작성해줘야합니다.
우리의 목적은 키보드를 만들 때는 삼성, 혹은 Lg로 나눠서 만드는 것이 목적이기에 팩토리메서드 방식을 이용해서 부품별로 만들기보다는, 중간에 SamsungComputerFactory, LgComputerFactory 로 한번 추상화를 더 해줘봅시다.
기존의 키보드, 마우스와 관련된 코드들은 동일합니다.
public class SamsungComputerFactory implements ComputerFactory {
public SamsungKeyboard makeKeyboard() {
return new SamsungKeyboard ();
}
public SamsungMouse makeMouse() {
return new SamsungMouse ();
}
}
public class LgComputerFactory implements ComputerFactory {
public LgKeyboard makeKeyboard() {
return new LgKeyboard ();
}
public LgMouse makeMouse() {
return new LgMouse ();
}
}
public interface ComputerFactory {
public Keyboard makeKeyboard();
public Mouse makeMouse();
}
public class FactoryOfComputerFactory {
public void makeComnputer(String brand){
ComputerFactory computerFactory= null ;
switch (brand){
case "Lg" :
computerFactory = new LgComputerFactory ();
break ;
case "Samsung" :
computerFactory = new SamsungComputerFactory ();
break ;
}
computerFactory.makeKeyboard();
computerFactory.makeMouse();
}
}
팩토리 메서드 패턴을 이용했을 때는 부품마다 팩토리를 만들어서 적용했습니다. 부품의 구현체 종류가 Samsung, Lg로 일정하고 우리가 원하는 것은 Samsung, Lg의 부품들을 모으는 것이기에 중간에서 Samsung 혹은 Lg 부품으로 한번에 캡슐화하여서 객체를 생성하였습니다.