S E P H ' S
[생성 패턴] 팩토리(Factory) 패턴 본문
팩토리(Factory) 패턴
팩토리 패턴은 객체를 생성하는 인터페이스는 미리 정의하되 인스턴스를 만들 클래스의 결정은 서브클래스에서 내리는 패턴이다. 다시 말해 여러 개의 서브 클래스를 가진 슈퍼 클래스가 있을 때 인풋에 따라 하나의 자식 클래스의 인스턴스를 리턴해주는 방식이다.
팩토리 패턴에서는 클래스의 인스턴스를 만드는 시점을 서브 클래스로 미룬다.
이 패턴은 인스턴스화에 대한 책임을 객체를 사용하는 클라이언트에서 팩토리 클래스로 가져온다.
언제 사용하는가?
- 어떤 클래스가 자신이 생성해야 하는 객체의 클래스를 예측할 수 없을 때
- 생성할 객체를 기술하는 책임을 자신의 서브 클래스가 지정했으면 할 때
팩토리 패턴에 사용되는 슈퍼 클래스는 인터페이스나 추상 클래스, 혹은 평범한 자바 클래스여도 상관없다.
Super Class
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();
}
}
Sub Class - 1
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;
}
}
Sub Class - 2
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;
}
}
PC 클래스와 Server 클래스 모두 Computer 클래스를 상속했다.
Factory Class
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;
}
}
ComputerFactory 클래스의 getComputer 메소드를 보면 static 메소드로 구현되었고, 메소드 내부를 보면 type의 값이 "PC"일 경우 PC의 인스턴스를 "Server"일 경우 Server의 인스턴스를 리턴하는 것을 볼 수 있다.
이렇게 팩토리 메소드 패턴을 사용하면 인스턴스를 필요로 하는 Application에서 Computer의 서브 클래스에 대한 정보는 모른채 인스턴스를 생성할 수 있게 된다.
이렇게 구현한다면 Computer 클래스에 더 많은 Sub 클래스가 추가된다 할지라도 getComputer()를 통해 인스턴스를 제공받던 Application의 코드는 수정할 필요가 없게 된다.
팩토리 메소드 패턴을 구현하는데 중요한 두 가지가 있다.
- Factory class를 Singleton으로 구현해도 되고, 서브클래스를 리턴하는 static 메소드로 구현해도 된다.
- 팩토리 메소드는 위 예제의 getComputer()와 같이 입력된 파라미터에 따라 다른 서브 클래스의 인스턴스를 생성하고 리턴한다.
마지막으로, 위 예제에서 작성한 ComputerFactory 클래스를 사용해 PC와 Server의 인스턴스를 생성해보자.
public class TestFactory {
public static void main(String[] args) {
Computer pc = ComputerFactory.getComputer("pc", "2 GB", "500 GB", "2.4 GHz");
Computer server = ComputerFactory.getComputer("server", "16 GB", "1 TB", "2.9 GHz");
System.out.println("Factory PC : " + pc);
System.out.println("Factory Server : " + server);
}
}
팩토리 패턴의 장점
- 팩토리 패턴은 클라이언트 코드로부터 서브 클래스의 인스턴스화를 제거하여 서로 간의 종속성을 낮추고, 결합도를 느슨하게 하며 (Loosely Coupled), 확장을 쉽게한다.
예를 들어, 위 예제에서 작성한 클래스 중 PC class에 대해 수정, 삭제가 일어나더라도 클라이언트는 알 수 없기 때문에 코드를 변경할 필요가 없다. - 팩토리 패턴은 클라이언트와 구현 객체들 사이에 추상화를 제공한다.
사용 예
- java.util 패키지에 있는 Calendar, ResourceBundle, NumberFormat 등의 클래스에서 정의된 getInstance() 가 팩토리 패턴을 사용하고 있다.
- Boolean, Integer, Long 등 Wrapper Class 안에 정의된 valueOf() 메소드 또한 팩토리 패턴을 사용했다.
'Programing & Coding > Design Pattern' 카테고리의 다른 글
[생성 패턴] 프로토타입(Prototype) 패턴 (0) | 2023.03.05 |
---|---|
[생성 패턴] 빌더(Builder) 패턴 (0) | 2023.03.05 |
[생성 패턴] 추상 팩토리 (Abstract Factory) 패턴 (0) | 2023.03.05 |
[생성 패턴] 싱글톤(Singleton) 패턴 (0) | 2023.03.04 |
디자인 패턴이란? (0) | 2023.03.04 |