공통으로 사용될 수 있는 특정한 기능들을 모듈화 한 것
프로그램을 설계할 때 발생했던 문제점들을 객체간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 '규약' 형태
Is using design patterns always a good idea?
디자인패턴은 문제해결에 대한 이점을 제공하는 것으로 알려져 있다. 하지만 과도하게 사용하면 부작용이 있을 수 있다.
따라서 개발자는 디자인패턴을 사용하는 것이 프로젝트에 효율적이고 적절한지 고려하고 대안적인 솔루션을 찾아 디자인패턴과 비교해야 한다. 디자인패턴을 채택하기 전에 디자인패턴의 고유한 제약 조건과 절충안을 이해하는 것이 중요하다.
객체의 인스턴스를 오직 하나만 생성하는 것
ex1. 데이터베이스 연결 모듈
ex2. Setting을 관리하는 클래스 (다크모드를 설정하면, 모든 페이지에 다크모드가 적용되어야 함)
객체 인스턴스를 어디서든지 액세스 할 수 있게 만들 수 있습니다. (하나의 인스턴스를 다른 모듈들이 공유하며 사용)
비용 절감 BUT 의존성 상승
생성자를 private으로 변경 -> 다른 클래스에서 new로 생성할 수 없게 된다
클래스 안에 자신의 타입을 갖는 객체를 선언한다
static 아닌 변수는 객체가 생성될 때마다 동적공간에 메모리가 할당되지만, static 변수는 메모리가 지정된 정적 공간에 딱 하나만 존재한다 (컴파일 할 때부터)
static 메소드는 이미 메모리의 정적 공간에 자리를 차지하고 있으므로 해당 객체를 new로 생성하지 않아도 바로 불러 사용할 수 있다
그냥 정적 변수를 쓰지 왜 싱글톤을 쓸까?
인터페이스의 사용이나 lazy loading 등 싱글톤으로 할수 있는 것들이 더 많기 때문에
인스턴스가 하나만 필요한 경우에 Singleton pattern을 사용한다. 클래스의 인스턴스화를 제한하여 데이터베이스, 저장소 및 파일과 같은 공유 리소스에 대한 제어를 유지하는 것이다.
최초로 인스턴스 생성 이후에는 생성자 호출 시 최초의 생성자가 생성한 인스턴스를 리턴한다.
모듈들이 더 분리가 되어 복잡성이 증가. (런타임 페널티 발생 가능성)
객체 생성 부분을 떼어내 추상화한 패턴
상속 관계에 있는 두 클래스에서 상위 클래스가 뼈대를 결정, 하위는 객체 생성의 구체적인 내용을 결정하는 패턴
Enum
상수의 집합을 정의할 때 사용되는 타입
상수 뿐만 아니라 메서드를 넣어 관리 할 수도 있음.
- 본질적으로 스레드세이프 하기 때문에 싱글톤 패튼을 만들 때 도움이 됨!
객체의 행위를 바꾸고 싶을 때, '직접' 수정하지 않고 전략이라 부르는 '캡슐화한 알고리즘'을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴이다.
ex. 우리가 물건을 살 때 네이버 페이, 카카오 페이 처럼 여러 방법으로 결제하듯, 결제 방식의 '전략'만 바꾸는 방식
컨텍스트
: 상황, 맥락, 문맥을 의미. 개발자가 어떠한 작업을 완료하는데 필요한 모든 관련 정보
특정한 계열의 알고리즘을 정의하고 각 알고리즘을 캡슐화하며 이 알고리즘들을 해당 계열 안에서 상호 교체가 가능하게 만든다.
기능 알고리즘을 Strategy라고 하는 독립적인 기능으로 분리하여 개발하도록 한다.
프로그램 실행 중 선택된 모드에 따라 실행되는 방식, 즉 전략이 결정될 때
예: 전체, 이미지, 뉴스, 지도 선택/검색 클릭 -> 검색할 때 선택한 검색 모드에 따라 각각 다른 검색 방식이 실행됨
위 예시를 전략패턴을 적용하지 않고 구현한다면?
SearchButton을 눌렀을 때 onClick함수에서 조건문을 사용해, 검색 모드에 따라 동작을 다르게 실행한다. 수정사항이 생기거나 모드가 추가되면 onClick은 한없이 길어짐 -> 소프트웨어가 커지고 복잡해 질수록 코드 분석,관리가 어려워지는 우아하지 않은 설계 && 클래스마다 역할지정을 뚜렷히 하여 모듈화 된 소프트웨어를 구축하는 객체지향 철학에 어긋남
전략패턴을 사용하면?
모드마다의 동작 하나하나를 모듈로 따로 분리하여 검색버튼을 누를 때 실행될 검색 모듈을 갈아끼워주는 방식 사용
SearchStrategy 인터페이스를 만들고 onClick에서 searchStrategy의 search() 함수만 호출한다. setter를 이용해 searchStrategy 를 SearchStategy 인터페이스를 상속 받은 다른 검색 전략으로 갈아끼울 수 있다.
전략 패턴을 활용한 라이브러리이다.
Node.js에서 인증 모듈을 구현할 때 쓰는 미들웨어 라이러버리로, 여러 가지 '전략'을 기반으로 인증할 수 있게 한다.
주체가 어떤 객체의 상태 변화를 관찰하다가 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변활르 알려주는 디자인 패턴이다.
객체와 주체가 분리되어 있다
주체 : 객체의 상태 변화를 보고 있는 관찰자
옵저버 : 이 객체의 상태 변화에 따라 전달되는 메서드를 기반으로 '추가 변화 사항'이 생기는 객체들을 의미
주체-객체 따로 두지 않고, 상태가 변경되는 객체를 기반으로 구축하기도 함
상속과 구현
- 상속(abstract class) : 자식 클래스가 부모 클래스의 메서드 등을 상속받아 사용하며 자식 클래스에서 추가 및 확장을 할 수 있다. -> 재사용성, 중복성의 최소화
- 구현(interface) : 부모 인터페이스를 자식 클래스에서 재정의하여 구현. 상속과 달리 반드시 부모 클래스의 메서드를 재정의하여 구현해야 한다.
객체 간에 일대다 종속성을 정의하여, 한 객체의 상태 변경이 다른 객체들에게 알려지게 하는 패턴.
Observer pattern은 수많은 객체 간의 일대다 관계인 경우의 기초입니다.
예로는 React를 사용하면 상태관리를 하는 Redux에 대해 들어본 적 있을 것이다. Redux는 Observer pattern의 구현으로 store에서 action에 따른 상태 업데이트에 따라 - Components가 변경 사항을 표현한다.
Redux는 단방향 데이터 바인딩으로 flux pattern으로도 많이 소개되며 flux는 facebook에서 만든 사용자 인터페이스 구축을 위한 아키텍처이다.
또한 원격 저장소에 코드가 반영되는 경우 CI 환경에서 변경 사항을 모니터링하고 빌드를 실행하는 것도 Observing된다고 할 수 있다.
❓ 옵저버 패턴 구현 방법
여러 방법이 있지만 프록시 객체를 써서 하곤 한다.
프록시 객체를 통해 객체의 속성이나 메서드 변화 등을 감지하고 이를 미리 설정해 놓은 옵저버들에게 전달하는 방법으로 구현함.
프록시 서버에서의 캐싱
: 캐시 안에 정보를 담아두고, 캐시 안에 있는 정보를 요구하는 요청에 대해 다시 멀리 있는 원격 서버에 요청하지 않고 캐시 안에 있는 데이터를 활용하는 것.
이를 통해 불필요하게 외부와 연결하지 않기 때문에 트래픽을 줄일 수 있다.
서버와 클라이언트 사이에서 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램이다.
❓ 프록시 서버 사용 사례
주로 Node.js 서버 앞단의 프록시 서버로 활용됨.(Node.js의 버퍼 오버플로우 취약점을 예방)
-> 이를 통해 익명 사용자가 직접 서버에 접근하는 것을 차단, 간접적으로 한 단계를 거치기 때문에 보안을 강화
버퍼 오버플로우
: 버퍼는 보통 데이터가 저장되는 메모리 공간으로 메모리 공간을 벗어나는 경우를 말한다. 이때 사용되지 않아야 할 영역에 데이터가 덮어씌워져 주소, 값을 바꾸는 공격이 발생하기도 한다.
전 세계적으로 서버가 분산되어 있음.
이를 통해 어떤 시스템의 콘텐츠를 빠르게 전달 할 수 있는 CDN 서비스이다.
이터레이터를 사용하여 컬렉션(collection)의 요소들에 접근하는 디자인 패턴이다.
이를 통해 순회할 수 있는 여러가지 자료형의 구조와는 상관없이 (어떤 컬렉션이든) 이터레이터라는 하나의 인터페이스로 순회가 가능하다.
즉시 실행 함수를 통해 private, public 같은 접근 제어자를 만드는 패턴이다.
Model-View-Controller 로 이루어짐
MVC 패턴을 이용한 대표적인 프레임워크
MVC로 부터 파생
커맨드
여러가지 요소에 대한 처리를 하나의 액션으로 처리하는 기법
데이터 바인딩
화면에 보이는 데이터와 웹 브라우저의 메모리를 일치시키는 기법. 뷰모델을 변경하면 뷰가 변경된다.
MVVM 패턴을 가진 대표적인 프레임워크
[Ref]
https://kimsangyeon-github-io.vercel.app/blog/2022-04-15-design-patterns
https://velog.io/@syoung125/객체지향-디자인-패턴-13가지