오늘은 디자인 패턴 스터디 첫번째 항목인 추상 팩토리 패턴에 대해 알아보도록 하겠습니다.
먼저, 디자인 패턴이란?
디자인 패턴이란, 프로그램을 개발하는 과정에서 빈번하게 발생하는 디자인 문제를 정리하여 상황에 따라 간편하게 적용할 수 있게 정리한 것입니다.
디자인 패턴을 공부하게되면, 가장 효과적이라고 알려진 방법들을 패턴화시켜, 단지 코드를 '재사용'하는 것이 아닌, 유지보수나 문서화를 개선, 클래스의 정확한 명세, 객체 간의 상호작용 또는 설계의 의도까지 명확하게 정의할 수 있습니다.
추상 팩토리 패턴(Abstract Factory Pattern)
추상 팩토리 패턴은 생성 패턴(Creational Pattern) 중 하나입니다.
생성 패턴은 인스턴스를 만드는 절차를 추상화 하는 패턴입니다.
생성 패턴에 속하는 패턴들은 객체를 생성, 합성하는 방법이나 객체의 표현 방법을 시스템과 분리해줍니다.
생성 패턴을 사용하게되면, 생성 패턴을 이용하면 무엇이 생성되고, 누가 이것을 생성하며, 이것이 어떻게 생성되는지, 언제 생성할 것인지를 결정하는 데 유연성을 확보할 수 있습니다.
추상 팩토리 패턴은 input으로 서브 클래스에 대한 식별 데이터를 받는 것이 아닌, 또 하나의 팩토리 클래스를 받습니다.
구상 클래스에 의존하지 않고 서로 연관되거나 의존적인 객체로 이루어진 제품군을 생산하는 인터페이스를 제공합니다.
구상 클래스는 서브 클래스에서 만듭니다.
위의 사진만으로는 이해가 어려울 수 있으니, 예제를 한번 작성해보도록 하겠습니다.
// 추상 팩토리 인터페이스
interface GUIFactory
Button createButton();
TextField createTextField();
}
추상 팩토리의 인터페이스를 정의합니다.
GUIFactory는 추상 팩토리의 인터페이스로,
createButton과 createTextField 라는 두개의 추상 메서드를 정의하고있습니다.
// 구체화된 팩토리 클래스
// Window용 구체적인 팩토리 클래스 구현
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
}
// MacOS용 구체적인 팩토리 클래스 구현
class MacOSFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacOSButton();
}
@Override
public TextField createTextField() {
return new MacOSTextField();
}
구체적인 팩토리 클래스들을 구현합니다.
WindowsFactory와 MacOSFactory는 각각 GUIFactory를 구현하는 구체적인 구체적인 팩토리 클래스로,
각각의 플랫폼에 맞는 Button과 TextField를 생성하고 있습니다.
// 추상 제품 인터페이스들
interface Button {
void paint();
}
interface TextField {
void paint();
}
추상 제품 인터페이스들을 정의합니다.
Button과 TextField는 추상 제품을 나타내는 인터페이스로,
paint라는 추상 메서드를 정의하고있습니다.
// 구체적인 제품 클래스들
class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("Windows style button");
}
}
class MacOSButton implements Button {
@Override
public void paint() {
System.out.println("MacOS-style button");
}
}
class WindowsTextField implements TextField {
@Override
public void paint() {
System.out.println("Windows-style text field");
}
}
class MacOSTextField implements TextField {
@Override
public void paint() {
System.out.println("MacOS-style text field");
}
}
구체적인 제품 클래스들을 구현합니다.
여기서 WindowsButton, MacOSButton, WindowsTextField, MacOSTextField는
각각의 Button과 TextField를 구현하는 구체적인 제품 클래스 입니다.
// 클라이언트 코드
public class Client {
public static void main(String[] args) {
// 플랫폼에 따라 적절한 팩토리 선택
GUIFactory factory;
String os = "Windows"; // 또는 "MacOS"
if (os.equals("Windows")) {
factory = new WindowsFactory();
} else if (os.equals("MacOS")) {
factory = new MacOSFactory();
} else {
throw new UnsupportedOperationException("Unsupported operating system");
}
// 팩토리를 이용하여 버튼과 텍스트 필드 생성
Button button = factory.createButton();
TextField textField = factory.createTextField();
// 생성된 컴포넌트 사용
button.paint();
textField.paint();
}
}
클라이언트 코드에서의 사용예시입니다.
클라이언트 코드에서는 GUIFactory를 이용하여, 플랫폼에 따라 적절한 Button과 TextField를 생성하고 사용합니다.
이를 사용하여, 구체적인 클래스에 직접 의존하지 않고, 추상화된 인터페이스를 통해 제품을 생성할 수 있습니다.
플랫폼에 따라 다르게 생성된 버튼과 텍스트 필드는 각자의 스타일을 가지며 사용됩니다.
추상 팩토리 패턴의 장점
유연성 및 확장성
추상 팩토리 패턴은 새로운 제품군을 도입하거나, 기존의 제품군을 변경 시, 팩토리 클래스만 변경하면 되므로 코드 변경을 최소화할 수 있습니다.
클라이언트 코드의 간결성
구체적인 제품 클래스에 직접 의존하지 않고, 추상 팩토리의 인터페이스를 통해 제품을 생성하므로, 코드가 간결해질 수 있습니다.
클라이언트 코드는 구체 클래스에 의존하지 않아 유지보수와 변경 또한 쉽습니다.
일관성 유지
팩토리가 제품을 생성하는 방식이 일관되어, 생성된 객체들 간의 일관성을 유지하기 편합니다.
코드 분리 및 모듈화
관련된 객체 생성 로직이 한 곳에 모여있어, 코드가 분리되어 있고, 따라서 모듈화가 됩니다.
추상 팩토리 패턴의 단점
복잡성 증가
제품군이나 팩토리의 계층이 복잡해지면, 새로운 제품이나 팩토리를 추가하는 것 또한 복잡해집니다.
생성되는 제품들 간의 관련성 필요
일정한 테마나 스타일을 가진 제품들을 생성하는 데 유용한 패턴이라, 관련성이 없는 경우에는 다른 생성 패턴을 고려하는 것이 적합합니다.
그래서 추상 팩토리 패턴은 어떤 코드에서 사용하는 것이 좋을까?
첫번째로, 특정 테마, 스타일 등의 제품군을 생성해야 할 때(위의 예시 코드와 비슷한 것들) 유용합니다.
두번째로, 시스템이나 라이브러리가 향후 확장이나 변경이 예상되는 경우, 기존 코드 변경을 최소화하며 유연하게 대처가 가능합니다.
세번째로, 클라이언트 코드가 특정 플랫폼이나 테마에 종속되면 안되는 경우, 추상 팩토리 패턴을 사용하여 추상화된 인터페이스를 통해 객체를 생성할 수 있습니다.
더 원활한 이해를 위해, 더 간단한 예시를 글로 써보겠습니다.
레스토랑 메뉴와 주방
추상 팩토리 : 메뉴판
메뉴판은 추상 팩토리이며, 여러 종류의 음식을 만들어내는데 필요한 추상적인 개념입니다.
구체적인 팩토리 : 한식 레스토랑, 양식 레스토랑
한식 레스토랑과 양식 레스토랑은 각각 추상 팩토리의 구현체입니다.
메뉴판(추상 팩토리)에 있는 음식들을 실제로 만들어내는 구체적인 공간입니다.
추상 제품 : 메뉴의 음식
메뉴판에 있는 각 음식은 추상 제품입니다.
예를들어, 된장찌개나 스테이크가 존재합니다.
구체적인 제품 : 한식 음식, 양식 음식
각 음식에 해당하는 실제 음식들이 구체적인 제품입니다.
된장찌개는 한식 음식 중 하나이고, 스테이크는 양식 음식 중 하나입니다.
클라이언트 : 손님
손님이 메뉴판(추상 팩토리)를 보고 한식 레스토랑(구체적인 팩토리)에서 된장찌개를 주문하면, 그에 해당하는 음식(구체적인 제품)이 나오게 됩니다.
이로써 첫번째 디자인 패턴 스터디인, 추상 팩토리 패턴을 완료했습니다.
이 글을 보시고, 제가 부족한 부분이나, 더 공부했으면 하는 부분이 있다면, 얼마든지 댓글로 피드백 부탁드립니다:)
참고자료
https://readystory.tistory.com/119
https://www.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS8616098823
GoF디자인 패턴 pdf
youtube
'Design Pattern' 카테고리의 다른 글
Design Pattern | 브리지 패턴(Bridge Pattern) (0) | 2024.08.29 |
---|---|
Design Pattern | 빌더 패턴(Builder Pattern) (2) | 2024.04.26 |
Design Pattern | 전략 패턴(Strategy Pattern) (0) | 2024.04.01 |
Design Pattern | 데코레이터 패턴(Decorator Pattern) (1) | 2024.03.22 |
Design Pattern | 컴포지트 패턴(Composite Pattern) (0) | 2024.02.22 |