지난 포스팅에 이어서 두번째 패턴 정리이다. 팩토리 패턴은 스프링에서 Bean Context(Application Context) 에서 상속받은 빈 팩토리와 연관되어 있는 만큼 알아 두는 것이 좋다고 판단해서 기록하고자 한다.
팩토리 패턴은 생성패턴이다.
생성 패턴은 인스턴스를 만드는 절차를 추상화하는 패턴이다.
생성 패턴에 속하는 패턴들은 객체를 생성, 합성하는 방법이나 객체의 표현 방법을 시스템과 분리해준다.
생성 패턴은 시스템이 상속(inheritance) 보다 복합(composite) 방법을 사용하는 방향으로 진화되어 가면서 더 중요해지고 있다.
생성 패턴에서는 중요한 이슈가 두 가지가 존재한다.
쉬운 말로 정리하자면, 생성 패턴을 이용하면 무엇이 생성되고, 누가 이것을 생성하며, 이것이 어떻게 생성되는지, 언제 생성할 것인지 결정하는 데 유연성을 확보할 수 있게 된다.
public abstract class Computer {
public abstract String getRAM();
public abstract String getHDD();
public abstract String getCPU();
@Override
public String toString(){
return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
}
}
public class PC extends Computer {
private String ram;
private String hdd;
private String cpu;
public PC(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public String getRAM() {
return this.ram;
}
@Override
public String getHDD() {
return this.hdd;
}
@Override
public String getCPU() {
return this.cpu;
}
}
public class Server extends Computer {
private String ram;
private String hdd;
private String cpu;
public Server(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public String getRAM() {
return this.ram;
}
@Override
public String getHDD() {
return this.hdd;
}
@Override
public String getCPU() {
return this.cpu;
}
}
public class ComputerFactory {
public static Computer getComputer(String type, String ram, String hdd, String cpu){
if("PC".equalsIgnoreCase(type))
return new PC(ram, hdd, cpu);
else if("Server".equalsIgnoreCase(type))
return new Server(ram, hdd, cpu);
return null;
}
}
위에서 type: String
이 어떠한 값이 들어오냐에 따라 생성자를 리턴해주는 스태틱 메서드를 가리킨다. 즉 DI 과정에서 new 연산자로 바로 생성해주는 것 보다 팩토리 클래스에서 매서드로 생성자를 주입해주는 것이 핵심이다.
참고로 스프링에서는 팩토리 클래스와 각 빈들을 싱글톤으로 관리해주기 때문에 프로토타입 빈 스코프가 아닌 경우에는 동일한 인스턴스를 주입해준다. (이전포스팅 참조)