추상 팩토리 패턴은 생성 패턴(Creational Pattern) 중 하나이다.
생성 패턴은 인스턴스를 만드는 절차를 추상화하는 패턴입니다.
생성 패턴에 속하는 패턴들은 객체를 생성, 합성하는 방법이나 객체의 표현 방법을 시스템과 분리해줍니다.
생성 패턴은 시스템이 상속(inheritance) 보다 복합(composite) 방법을 사용하는 방향으로 진화되어 가면서 더 중요해지고 있습니다.
생성 패턴에서는 중요한 이슈가 두 가지 있습니다.
- 생성 패턴은 시스템이 어떤 Concrete Class를 사용하는지에 대한 정보를 캡슐화합니다.
- 생성 패턴은 이들 클래스의 인스턴스들이 어떻게 만들고 어떻게 결합하는지에 대한 부분을 완전히 가려줍니다.
쉬운 말로 정리하자면, 생성 패턴을 이용하면 무엇이 생성되고, 누가 이것을 생성하며, 이것이 어떻게 생성되는지, 언제 생성할 것인지 결정하는 데 유연성을 확보할 수 있게 됩니다.
추상 팩토리 패턴(Abstract Factory Pattern)이란?
팩토리 메소드 패턴에서는 하나의 팩토리 클래스가 인풋으로 들어오는 값에 따라 if-else나 switch 문을 사용하여 다양한 서브클래스를 리턴하는 형식으로 구현했었습니다.
추상 팩토리 패턴에서는 팩토리 클래스에서 서브 클래스를 생성하는 데에 있어 이러한 if-else 문을 걷어냅니다.
추상 팩토리 패턴은 인풋으로 서브클래스에 대한 식별 데이터를 받는 것이 아니라 또 하나의 팩토리 클래스를 받습니다.
1) super class 작성
package com.patterns.abstractFactory1;
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();
}
}
2) sub class작성 : PC,Server ...
package com.patterns.abstractFactory1;
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;
}
}
package com.patterns.abstractFactory1;
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;
}
}
여기까지는 팩토리 패턴과 동일
3)추상 팩토리의 역활을 하는 인터페이스 또는 추상클래스가 필요함 -> Factroy
package com.patterns.abstractFactory1;
public interface ComputerAbstractFactory {
public Computer createComputer();
}
여기서 주의 깊게 보실 것은 위에서 작성한 팩토리 인터페이스의 createComputer() 메소드의 리턴 타입이 super class인 Computer라는 것입니다. 이제 이 팩토리 인터페이스를 구현(implements)하는 클래스에서 createComputer() 메소드를 오버라이딩 하여 각각의 서브 클래스를 리턴해줄 것입니다. 이는 자바의 다형성을 아주 잘 활용한 방식이라 볼 수 있습니다.
4) PCFactory, ServerFactory ...
package com.patterns.abstractFactory1;
public class PCFactory implements ComputerAbstractFactory {
private String ram;
private String hdd;
private String cpu;
public PCFactory(String ram, String hdd, String cpu) {
this.ram = ram;
this.hdd = hdd;
this.cpu = cpu;
}
@Override
public Computer createComputer() {
return new PC(ram, hdd, cpu);
}
}
package com.patterns.abstractFactory1;
public class ServerFactory implements ComputerAbstractFactory {
private String ram;
private String hdd;
private String cpu;
public ServerFactory(String ram, String hdd, String cpu) {
this.ram = ram;
this.hdd = hdd;
this.cpu = cpu;
}
@Override
public Computer createComputer() {
return new Server(ram, hdd, cpu);
}
}
5) 제 마지막으로 이 서브 클래스들을 생성하기 위해 클라이언트 코드에 접점으로 제공되는 컨슈머 클래스(consumer class)를 만들어보겠습니다.
※ consumer -> 소비자
package com.patterns.abstractFactory1;
public class ComputerFactory {
public static Computer getComputer(ComputerAbstractFactory factory) {
return factory.createComputer();
}
}
이제 클라이언트는 이 ComputerFacotry 클래스의 getComputer()라는 static 메소드에 앞서 구현한 PCFactory나 ServerFactory 인스턴스를 넣어줌으로써if-else 없이도각각 원하는 서브 클래스의 인스턴스를 생성할 수 있게 됐습니다.
6) test
package com.patterns.abstractFactory1;
public class AbstractFactoryTest {
public static void main(String[] args) {
Computer pc = ComputerFactory.getComputer(new PCFactory("2 GB", "500 GB", "2.4 GHz"));
Computer server = ComputerFactory.getComputer(new ServerFactory("16 GB", "1 TB", "2.9 GHz"));
System.out.println("AbstractFactory PC Config::" + pc);
System.out.println("AbstractFactory Server Config::" + server);
}
}
결국 모델은
추상 팩토리 패턴의 장점
- 추상 팩토리 패턴은 구현(Implements)보다 인터페이스(Interface)를 위한 코드 접근법을 제공합니다.
위 예에서 getComputer() 메소드는 파라미터로 인터페이스를 받아 처리를 하기 때문에 getComputer() 에서 구현할 것이 복잡하지 않습니다. - 추상 팩토리 패턴은 추후에 sub class를 확장하는 데 있어 굉장히 쉽게할 수 있습니다.
위 예에서 만약 Laptop 클래스를 추가하고자 한다면 getComputer()의 수정 없이 LaptopFactory만 작성해주면 됩니다.
이러한 특징에 기반하여 추상 팩토리 패턴은 "Factory of Factories"라고도 불립니다. - 추상 팩토리 패턴은 팩토리 패턴(팩토리 메소드 패턴)의 조건문(if-else, switch 등)으로부터 벗어납니다.
참고자료 : https://readystory.tistory.com/119
[생성 패턴] 추상 팩토리 패턴(Abstract Factory Pattern) 이해 및 예제
이번에 살펴볼 디자인 패턴은 생성 패턴 중 하나인 추상 팩토리 패턴(Abstract Factory Pattern)입니다. 추상 팩토리 패턴은 이전 포스팅에서 살펴본 팩토리 패턴(Factory Pattern)과 유사한 패턴으로, 팩토
readystory.tistory.com
https://www.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS8616098823
[Design pattern] 많이 쓰는 14가지 핵심 GoF 디자인 패턴의 종류
디자인 패턴을 활용하면 단지 코드만 ‘재사용’하는 것이 아니라, 더 큰 그림을 그리기 위한 디자인도 재사용할 수 있습니다. 우리가 일상적으로 접하는 문제 중 상당수는 다른 많은 이들이 접
www.hanbit.co.kr
'IT > 다자인 패턴' 카테고리의 다른 글
1.5 프로토타입 패턴은 생성 패턴(Creational Pattern)........ 생성(Creational) 패턴중 (0) | 2022.08.07 |
---|---|
1.4 빌더 패턴은 생성 패턴(Creational Pattern) ........ 생성(Creational) 패턴중 (0) | 2022.08.07 |
1.3 팩토리 메소드 패턴(Factory method pattern)........ 생성(Creational) 패턴중 (0) | 2022.08.07 |
1.1 싱글턴(Singleton) :: 생성(Creational) 패턴 (0) | 2022.08.07 |
디자인 패턴 (0) | 2022.08.07 |