reference: https://gmlwjd9405.github.io/2018/07/06/design-pattern.html
23가지의 디자인 패턴이 존재한다. 각각의 디자인 패턴은 생성(Creational), 구조(Structural), 행위(Behavioral) 3가지로 패턴으로 분류된다.
source: https://gmlwjd9405.github.io/2018/07/06/design-pattern.html
객체 생성에 관련된 패턴이다. 객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 유연성을 제공한다.
: 구제적인 클래스에 의존하지 않고 서로 연관되거나 의존적인 객체들의 조합을 만드는 인터페이스를 제공하는 패턴
=> 하나의 팩토리에 조건문 형태로 구체 클래스를 생성하는 방식은 SRP 원칙에 위배한다.
따라서 추상 팩토리 클래스를 만들고, 구체적인 객체들이 구체 팩토리 클래스에서 생성되도록 한다.
: 객체 생성 처리를 서브 클래스로 분리해 처리하도록 캡슐화하는 패턴
클라이언트 코드에서 객체 생성에 대한 책임을 덜 수 있는 것이 팩토리 메서드(또는 팩토리 클래스)의 장점이다. 그저 원하는 객체를 생성하기 위해 객체의 클래스에 정의된 static 메서드를 호출하면 된다.
이를 통해 직접적인 생성을 통해 발생하는 의존성을 줄일 수 있으며, 이름이 직관적인 함수를 사용할 수 있다는 장점도 있다.
직접 생성자를 호출하고 싶지 않은 이유
다른 코드의 변화로부터 독립적인 코드의 작성에 생성자가 걸림돌이 될 수 있다. 생성자는 각각 확정된 객체(Concrete object)가 있어야 호출될 수 있으며, 확정된 객체에 변화가 생기면 잠재적으로 수정될 가능성이 생긴다. 이는 곧 생성자를 직접 호출한 코드에서도 수정이 필요함을 의미한다. 따라서 생성자를 따로 관리할 수 있다면 좀 더 변화에 대응하기 쉬울 것이다.
: 전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴
인스턴스가 두 개 이상이 생성되면 프로그램이 의도치 않게 동작한다든가 자원을 불필요하게 잡아먹는다든가 결과에 일관성을 해치는 심각한 문제가 발생할 수 있다. 이러한 객체는 싱글톤 패턴을 적용하여 유일한 객체로서 생성되도록 하는 것이다.
클래스나 객체를 조합해 더 큰 구조를 만드는 패턴이다. 예를 들어 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스를 제공하거나 객체들을 서로 묶어 새로운 기능을 제공하는 패턴이다.
: 여러 개의 객체들로 구성된 복합 객체와 단일 객체를 클라이언트에서 "구별 없이" 다루게 해주는 패턴
세 가지 종류의 타입이 수행하는 역할은 다르나 이 타입을 사용하는 주체(Field)는 타입의 역할에 관계없이 "동일한" 인터페이스를 통하여 타입 객체의 역할을 수행할 수 있도록 해야 했기 때문이다. 이러한 문제를 해결하기 위해 Composite Pattern을 적용
:객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 해주는 패턴
기본 기능에 추가할 수 있는 기능의 종류가 많은 경우 각 추가 기능을 Decorator 클래스로 정의한다.
여러 기능을 동적으로 추가, 삭제할 수 있도록 만들어주는데에 중점을 둔다.
3. 행위(Behavioral) 패턴
객체나 클래스 사이의 알고리즘이나 책임 분배에 관련된 패턴
한 객체가 혼자 수행할 수 없는 작업을 여러 개의 객체로 어떻게 분배하는지, 또 그렇게 하면서도 객체 사이의 결합도를 최소화하는 것에 중점을 둔다.
옵서버(Observer)
: 한 객체의 상태 변화에 따라 다른 객체의 상태도 연동되도록 일대다 객체 의존 관계를 구성하는 패턴
옵저버 패턴은 'Loosely coupled'를 향상시킨다.
주체(subject)가 옵저버에 대해서 알아야 할 것은 오직 옵저버의 인터페이스 뿐이다(update() 함수). 그리고 옵저버는 직접적인 요청을 하는 것이 아닌 자동으로 새로운 정보를 얻을 수 있다.
또한 새로운 타입의 옵저버가 추가될 때 주체(subject)를 수정할 필요가 없다(옵저버 인터페이스를 구현하는 방식이기에). 즉 하나의 컴포넌트의 변화는 다른 컴포넌트에 영향을 미치지 않는다.
스테이트(State)
: 객체의 상태에 따라 객체의 행위 내용을 변경해주는 패턴
스트래티지(Strategy)
: 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴
템플릿 메서드(Template Method)
: 어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴
커맨드(Command)
: 실행될 기능을 캡슐화함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스를 설계하는 패턴
=> 캡슐화한다는 것은 재사용성을 높이고, "결합을 약하게 하여 수정에 대한 영향을 덜 받게 하는 것"이다. 나아가 "캡슐화된 객체/행위에 대한 올바른 usage를 제공하는 것"과 같다.
ex) 객체의 상태를 전달하여 로직을 구성하는 것이 아닌, 로직의 산출 값을 반환받는다.
ex) 템플릿 메서드와 같은 경우는 구조를 그대로 재사용하면서, 특정 로직을 임의로 바꾸지 않도록 하는 것이다.