Creational patterns
생성 패턴이란.
우선 에릭 감마를 비롯한 4인방의 소개를 읽어보자. 어렵지 않은 단어와 문장이니, 의미를 생각해보며 정독해보자.
Creational design patterns abstract the instantiation process. They help make a system independent of how its objects are created, composed, and represented. A class creational pattern uses inheritance to vary the class that's instantiated, whereas an object creational pattern wiil delegate instantiation ot another object.
Creational patterns become important as systems evolve to depend more on object composition than class inheritance. As that happens, emphasis shifts away from hardcoding a fixed set of behaviors toward defining a smaller set of fundamental behaviors that can be composed into any number of more complex ones. Thus creating objects with particular behaviors requires more than simply instantiating a class.
These are two recurring themes in these patterns. First, they all encapsulate knowledge about which concrete classes the system uses. Second, they hide how instances of these classes are created and put together. All the system at large knows about the objects is their interfaces as defined by abstract classes. Consequently, the creational patterns give you a lot of flexibility in what gets created, who creates it, how it gets created, and when. They let you configure a system with "product" objects that vary widely in strcuture and functionality. Configuration can be static (that is, specified at compile-time) or dynamic (at run-time).
생성 패턴은 "인스턴스를 만드는 절차"를 추상화하는 패턴이다. 객체의 다양성을 주고 싶을 때에, 클래스의 상속을 이용할 수 있다. 하지만 상속을 이용한다고 하더라도 고정된 행동 집합을 하드 코딩하여 객체의 다양성을 주는 것은 한계가 있다. 이에 작은 단위의 행동 집합들을 정의하고, 이들을 조합하며 객체를 생성하는 것이 객체 생성 패턴이며, 이는 객체의 다양성과 유연성을 준다.
여기서 유연성에 집중하여 생성 패턴을 공부한다면 의도(Intent)를 조금 더 빠르게 파악할 수 있다.
클래스 생성 패턴 예제
먼저 기존의 클래스 생성 패턴을 살펴보자. (코드를 삽입할 수 있는 수단이 없어, GitHub 링크로 대체하였다.)
Creational pattern example code link
Main.java를 열어보자. (구조 설명은 추후에 추가하도록 하겠다.)
단지 Maze 객체를 생성하고, Room 객체 2개를 추가하기 위해서 8줄이 넘는 코드라인이 사용되었다. 사실 코드라인 개수가 중요한 것이 아니라 유연성에 있어서 문제점이 크다.
Room에 설정할 Door의 종류를 다양하게 해야 하는 요구사항이 새롭게 생긴다면, 개발자는 기존 Door와 마찬가지로 MapSite 클래스를 상속받아 새로운 요구사항에 맞추어 클래스를 작성할 것이다. 하지만 조금씩 요구사항이 추가되거나 바뀐다면, 새롭게 작성해야 하는 Door의 클래스는 점차 증가할 것이다. 또한 작성된 Door가 A라는 요구사항에 의하여 작성되었다면, 오직 A라는 요구사항에만 적합하며, A', A'' 등의 요구사항이 생긴다면 개발자는 매번 새로운 클래스를 추가해야 한다.
예를 들어, 자물쇠가 존재하는 Door가 새로운 요구사항으로 생긴다면, 개발자는 MapSite 클래스를 상속하여 자물쇠, 열쇠와 관련된 변수와 행동들을 추가한 새로운 Door 클래스를 새로 작성해야 한다. 이번엔 전자도어록을 사용하는 Door가 새로운 요구사항으로 등장한다면, 이전에 작성했던 Door 클래스로는 사용이 불가능하다. 이에 개발자는 전자도어록을 사용하는 Door만을 위한 클래스를 작성해야 한다. 이는 분명 불필요한 행위이며 코드의 유연성이 없다.
위 코드를 개선하기 위해 생성 패턴을 적용해보자.
레오나르도 다빈치의 최후의 만찬
이 작품은 가톨릭 성경에 등장하는 예수의 마지막 날의 최후의 만찬의 정경을 그린 것이다. 이 장면에는 '너희 중 하나가 나를 팔리라'(요한복음 13장 21절)라는 말씀에 제자들은 각양각색의 반응을 표시하며 심한 동요가 일어난다.
1쇄. 2020.12.01.