Design pattern
디자인 패턴이란, 반복적으로 발생하는 문제를 어떻게 풀어낼것인가에 대한 일종의 솔루션입니다.
가장 많이 사용되는 디자인 패턴은 GoF의 디자인 패턴이 있습니다.
GoF는 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, 네명의 프로그래머들이 고안한
디자인 패턴입니다.
GoF 디자인 패턴에는 목적에 따라 생성 패턴, 구조패턴, 행동 패턴로 나뉩니다.
오늘 글에선
생성 패턴과 구조 패턴의 Decorator 패턴 까지 설명하도록 하고
나머지는 다음 글에서 작성하도록 하겠습니다.
1. 생성 패턴
먼저 생성패턴입니다.
생성 패턴은 객체를 어떠한 방식으로 생성할지에 대한 패턴입니다.
1-1) 싱글톤 ( SIngleton )
싱글톤 패턴은 시스탬 내에서 객체의 인스턴스가 오직 한개만 생성하도록 하는 패턴입니다.
싱글톤 패턴은 메모리 측면에서 이점을 얻기 위함과 셋팅 객체 등에 활용 됩니다.
만약 셋팅 객체를 통하여 Dark Mode를 제어한다고 가정하였을때
인스턴스가 여러 개 생성되었을때 의도하지 않은 동작을 할 수 있습니다.
싱글톤 패턴을 구현하는데 있어서는
Eager Initialization ( 이른 초기화 방식 ), Lazy Initialization ( 늦은 초기화 방식 ), Thread safe Lazy Initialization ( 멀티스레드에서 안전한 늦은 초기화 방식 ), Double Checkked locking 방식, Initialization on demand holder idiom ( holder에 의한 초기화 방식 )이 있습니다.
https://www.youtube.com/watch?v=OwOEGhAo3pI&list=PLfI752FpVCS_v_sc8Q6V9QQN7GhoyktKD
https://www.youtube.com/watch?v=bHRETd1rFfc&list=PLfI752FpVCS_v_sc8Q6V9QQN7GhoyktKD&index=2
https://www.youtube.com/watch?v=bAYGNP-FevQ&list=PLfI752FpVCS_v_sc8Q6V9QQN7GhoyktKD&index=3
해당 방식들에 대한 이야기는 백기선님 유튜브에서 잘 설명되고 있으니 해당 링크 참고하시면 좋을 것 같습니다.
1-2) 팩토리 메소드 ( Factory Method )
팩토리 메소드 패턴은 객체를 클래스가 직접 생성하지 않고 객체 생성을 담당하는 Factory 객체를 사용하는 패턴입니다.
장점으로는 직접 객체를 생성하는 것을 막아주기 때문에 결합도를 낮춰주는 효과가 있습니다.
1-3) 추상 팩토리 ( Abstract Factory )
추상 팩토리 패턴은 서로 관련 있는 객체들을 통째로 묶어서 팩토리 클래스로 만들고, 이를 조건에 따라 생성하도록 다시 팩토리를 만들어서 객체를 생성하는 패턴입니다.
1-4) 빌더 ( Builder )
빌더 패턴은 객체를 생성하는 클래스와 표현하는 클래스를 분리하는 패턴으로, 생성자만을 사용할 때 발생할 수 있는 문제를 개선하기 위한 패턴입니다.
먼저 생성자만을 사용하게 되면
- 프로그램에서 팩토리 클래스를 호출 시 Optional한 인자가 많다면, 타입 혹은 순서에 대한 관리가 어려워지고 이는 에러로 이어질 가능성이 높아집니다.
- 경우에 따라 필요 없는 필드들에 대하여 일일이 Null값을 넘겨주어야 합니다.
- 생성해야 하는 클래스가 무거워지고 복잡해질 수 있습니다.
이를 개선할 수 있는 방법이 바로 빌더 패턴입니다.
1-5) 프로토타입 ( Prototype )
프로토타입 패턴은 new 키워드를 사용하지 않고 객체를 복제해 생성하는 패턴입니다.
new 키워드를 통해 객체를 생성하는 비용이 많이 들 수 있다면 프로토 타입을 적용하는 것도 방법이 될 수 있습니다.
객체를 복제하여 사용하면 인스턴스 생성 과정이 생략되어 생성 로직에서 소모되는 처리비용과 자원을 절약할 수 있습니다.
2. 구조 패턴
구조 패턴이란 클래스나 객체를 조합하여 더 큰 구조를 만드는 패턴입니다.
예를 들어 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스 형식으로 제공하거나 서로 묶어 새로운 기능을 제공할 수 있도록 하는 패턴입니다.
2-1) 어댑터 ( Adapter )
어댑터 패턴은 특정 인터페이스에 대하여 구현체로 등록하고 싶으나 호환되지 않는 인터페이스를 호환할 수 있도록 하는패턴입니다.
만약 건설사라는 인터페이스에서 built라는 메소드가 있다는 가정이 있고 A 건설사에선 똑같은 행동을 하지만 명칭만 다른 make라는 메소드가 있다고 가정 하였을때
이에 대한 호환을 위한 Adapter 클래스를 만들고 건설사 인터페이스의 구현체로 잡은 후
이름을 built로 작성한 후 안에선 make 메소드가 실행하도록 하는 방법이 있을 수 있습니다.
2-2) 컴포지트 ( Composite )
컴포지트 패턴은 객체들의 관계를 트리 구조로 구성하여 부분과 전체 계층을 표현하는 계층입니다.
사용자는 컴포지트 패턴을 통해 단일 객체와 복합 객체 모두 동일하게 다룰 수있습니다.
즉, 전체-부분 관계를 갖는 객체들의 관계를 정의할때 유용하고, 클라이언트는 이를 구분하지 않고 동일한 인터페이스를 사용할 수 있다는 장점이 있습니다.
ex) 폴더와 파일 트리
2-3) 데코레이터 ( Decorator )
데코레이터 패턴은 특정 클래스의 객체들이 할 수 있는 여러가지 두고 각 객체마다 사용자가 원하는대로 골라 시키거나
기능들을 필요에 따라 장착할 수 있도록 할때 사용되는 패턴입니다.