개발자 yeah의 Developer Story - 디자인 패턴
오늘은 저번 포스팅에 이어서 팩토리 메서드 패턴의 확장 패턴인 추상 팩토리 패턴을 이야기해보려 합니다.
먼저 추상 클래스를 상속받은 하위 클래스의 특징을 설명하도록 하겠습니다.
추상클래스에서 정의한 추상 메서드 를 이용하여 각각의 하위 클래스는 이를 오버라이드 하여 목적에 맞도록 실제 동작하는 메서드를 구현 하게 됩니다.
만약 목적에 따라 다른 하위클래스가 필요하게 된다면, 그 목적에 따라 실제 동작하는 메서드는 저 마다 다르게 구현 할 수 있습니다.
이를 객체지향에서 다형성 이라고 부릅니다.
추상화 된 Factory 클래스를 통한 객체 생성은 2가지 방법이 존재하게 되는데요.
첫 번째는 지난 포스팅에서 배운 팩토리 메서드 패턴 입니다.
팩토리 메서드 패턴 은 추상화를 통하여 하위 클래스에게 구현을 위임하였으며, 1개의 하위 클래스 안에서 매개변수를 통하여 조건에 따라 각각의 객체 생성을 하였습니다.
즉 다형성 을 배제한 방법인 것이죠.
두 번째는 위에서 언급한 다형성을 적극적으로 이용한 추상 팩토리 패턴 입니다.
추상 팩토리 패턴 은 생성해야 될 각각의 객체마다 하위 클래스(Factory) 를 생성하여, 원하는 하위 클래스(Factory) 를 결합하도록 하는 방식입니다.
즉 복수의 하위 클래스(Factory) 를 갖는 구조인 것이죠.
자 그럼 이제 코드를 살펴보도록 하겠습니다.
먼저 기존 팩토리 메소드 패턴 에서 활용했던 객체들을 그대로 사용하여 설명하겠습니다.
/* 마피아 게임에서 사용자를 나타내는 class */
abstract class User {
String name; //사용자 이름
String skill; //스킬
User(String name) { this.name = name; }
String getName() { return name; }
String getSkill() { return skill; }
}
/* 마피아 게임에서 시민을 나타내는 class */
public class Citizen extends User{
Citizen(String name) {
super(name);
System.out.println(name + " 님은 시민으로 생성 되었습니다.");
setSkill();
}
void setSkill() {
this.skill = "투표를 행사 할 수 있음.";
System.out.println(name + " 님은 시민 스킬을 장착하였습니다.\n");
}
}
/* 마피아 게임에서 마피아를 나타내는 class */
public class Mafia extends User {
Mafia(String name) {
super(name);
System.out.println(name + " 님은 마피아로 생성 되었습니다.");
setSkill();
}
void setSkill() {
this.skill = "시민을 죽일 수 있음.";
System.out.println(name + " 님은 마피아 스킬을 장착하였습니다.\n");
}
}
/* 마피아 게임에서 경찰을 나타내는 class */
public class Police extends User {
Police(String name) {
super(name);
System.out.println(name + " 님은 경찰로 생성 되었습니다.");
setSkill();
}
void setSkill() {
this.skill = "마피아를 찾을 수 있음.";
System.out.println(name + " 님은 경찰 스킬을 장착하였습니다.\n");
}
}
User(사용자)라는 추상 클래스가 있고 이를 상속받는 Mafia(마피아), Police(경찰), Citizen(시민) 클래스가 있습니다.
기존 팩토리 메서드 패턴 에서 정의한 추상클래스를 수정없이 그대로 사용하겠습니다.
/* 객체 생성의 위임을 위한 Factory class */
abstract class Factory {
/* 추상화를 결합한 추상 팩토리 패턴의 상위 클래스 */
public final User create(String name) {
//하위 클래스로 위임
return this.createUser(name);
}
abstract public User createUser(String name);
}
위 코드를 보시면 추상클래스에서 정의한 추상 메서드 createUser()를 통해 하위 클래스에 구현부를 위임하고,
create()를 통해 하위클래스에 위임한 함수를 실행하도록 설계되어 있습니다.
이에 따라 해당 Factory 를 상속받는 하위 클래스들은 저 마다 특징에 맞도록 구현부를 다르게 작성 할 수 있습니다. (다형성)
다음은 Factory를 상속받을 각각의 하위 클래스 입니다.
/* Citizen 객체 생성을 담당할 하위 Factory */
public class CitizenFactory extends Factory {
@Override
public User createUser(String name) {
return new Citizen(name); //Citizen 객체를 생성.
}
}
/* Mafia 객체 생성을 담당할 하위 Factory */
public class MafiaFactory extends Factory {
@Override
public User createUser(String name) {
return new Mafia(name); //Mafia 객체를 생성.
}
}
/* Police 객체 생성을 담당할 하위 Factory */
public class PoliceFactory extends Factory {
@Override
public User createUser(String name) {
return new Police(name); //Police 객체를 생성.
}
}
기존 팩토리 메서드 패턴 과 달리 각각의 하위클래스에서 목적에 해당되는 객체를 생성하는 것을 볼 수 있습니다.
다음은 main() 에서 어떻게 처리되는지 확인하도록 하겠습니다.
public class AbstractFactoryPattern {
/* 마피아 게임 */
public static void main(String[] args) {
Factory factory = new MafiaFactory();
User user1 = factory.create("성민");
factory = new PoliceFactory();
User user2 = factory.create("영성");
factory = new CitizenFactory();
User user3 = factory.create("승주");
User user4 = factory.create("수지");
System.out.println("이름 : " + user1.getName() + ", 스킬 : " + user1.getSkill());
System.out.println("이름 : " + user2.getName() + ", 스킬 : " + user2.getSkill());
System.out.println("이름 : " + user3.getName() + ", 스킬 : " + user3.getSkill());
System.out.println("이름 : " + user4.getName() + ", 스킬 : " + user4.getSkill());
}
}
이전 팩토리 메서드 패턴 에서는 하나의 하위 클래스를 통하여 create() 했지만,
추상 팩토리 패턴 에서는 각각의 객체 생성을 담당하는 하위 Factory 를 결합하여 create()를 호출하는 것을 확인할 수 있습니다.
다음은 main() 의 결과 창입니다.
팩토리 메서드 패턴 VS 추상 팩토리 패턴
추상 팩토리 패턴 은 팩토리 메서드 패턴의 확장이라고 볼 수 있지만, 더 좋은 패턴이라고는 단정 지을 수는 없습니다.
추상 팩토리 패턴 은 동일한 처리로직의 하위클래스의 결합을 통해 선택적으로 객체를 생성 할 수 있는 장점이 있지만,
새로운 객체가 추가된다면 하위 클래스도 같이 추가돼야 하고 확장 시 모든 하위클래스의 수정이 필요 할 수도 있습니다.
팩토리 메서드 패턴 은 1개의 하위클래스 내 매개변수 를 통해 생성을 선택적으로 처리하기에 다형성의 단점은 해결할 수 있지만,
새로운 객체가 추가된다면 조건이 추가 되어야 하고 확장 시 하위클래스의 덩치가 커지기 때문에 유지보수가 어려울수 있습니다.
따라서 본인이 진행하고 있는 프로젝트의 규모와 설계에 따라 적절한 패턴을 사용하는 것이 좋습니다!
이렇게 오늘은 팩토리 메서드 패턴 을 확장한 추상 팩토리 패턴 을 이야기 해봤는데요.
궁금하시거나 질문이 있으시면 댓글로 달아주세요 !!
감사합니다!
'Software Development > 디자인 패턴' 카테고리의 다른 글
[디자인 패턴의 정석] 생성패턴 - 프로토 타입 패턴 (Prototype) (15) | 2020.12.19 |
---|---|
[디자인 패턴의 정석] 생성패턴 - 빌더 패턴 (Builder) (5) | 2020.12.18 |
[디자인 패턴의 정석] 생성패턴 - 싱글턴 패턴 (Singleton) (17) | 2020.12.15 |
[디자인 패턴의 정석] 생성패턴 - 팩토리 메서드 패턴 (Factory Method) (25) | 2020.12.10 |
[디자인 패턴의 정석] 생성패턴 - 팩토리 패턴 (Factory) (17) | 2020.12.06 |