EverGiver

1.1 디자인 패턴 본문

취뽀/CS 지식

1.1 디자인 패턴

친절한개발초보자 2022. 9. 17. 20:01
728x90
  • 디자인 패턴이란?
    - 프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 '규약' 형태로 만들어 놓은 것

싱글톤 패턴

 

  • 싱글톤 패턴(singleton pattern)
    - 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
  • 싱글톤 패턴 특징
    - 보통 데이터베이스 모듈에 많이 사용
    - 하나의 인스턴스를 만들어 놓고 해당 인스턴스를 다른 모듈들이 공유하며 사용하기 때문에 인스턴스를 생성할 때 드는 비용이 줄어드는 장점
    - 의존성이 높아진다는 단점
  • 자바스크립트의 싱글톤 패턴
    - 자바스크립트에서는 리터럴 {} 또는 new Object로 객체를 생성하게 되면 다른 어떤 객체와도 같지 않기 때문에 이 자체만으로 싱글톤 패턴을 구현할 수 있다.
  • mongoose의 싱글톤 패턴
    - Node.js에서 MongoDB 데이터베이스를 연결할 때 쓰는 mongoose 모듈에서 볼 수 있다.
    - mongoose의 데이터베이스를 연결할 때 쓰는 connect()라는 함수는 싱글톤 인스턴스를 반환한다.
  • MySQL의 싱클톤 패턴
    - Node.js에서 MySQL 데이터베이스를 연결할 때도 싱글톤 패턴이 사용된다.
  • 싱글톤 패턴의 단점
    - TDD(Test Driven Development)를 할 때 걸림돌이 된다.
    - TDD를 할 때 단위 테스트를 주로 하는데, 단위 테스트는 테스트가 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야 한다.
    - 하지만 싱글톤 패턴은 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴이므로 각 테스트마다 독립적인 인스턴스를 만들기가 어렵다.
  • 의존성 주입
    - 싱글톤 패턴은 사용하기 쉽고 실용적이지만 모듈 간의 결합을 강하게 만들 수 있다는 단점 존재
    - 이때 의존성 주입(DI, Dependency Injection)을 통해 모듈간의 결합을 조금 더 느슨하게 만들어 해결할 수 있다.
    - 의존성이란 종속성이라고도 하며 A가 B에 의존성이 있다는 것은 B의 변경 사항에 대해 A 또한 변해야 된다는 것을 의미
    - 메인 모듈(main module)이 '직접' 다른 하위 모듈에 대한 의존성을 주기보다는 중간에 의존성 주입자가 이 부분을 가로채 메인 모듈이 간접적으로 의존성을 주입하는 방식
    - 모듈들을 쉽게 교체할 수 있는 구조가 되어 테스팅하기 쉽고 마이그레이션하기도 수월하다는 장점이 있다.
    - 구현할 때 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어 주기 때문에 애플리케이션 의존성 방향이 일관되고, 애플리케이션을 쉽게 추론할 수 있으며, 모듈 간의 관계들이 조금 더 명확해지는 장점이 있다.
    - 모듈들이 더욱더 분리되므로 클래스 수가 늘어나 복잡성이 증가될 수 있으며 약간의 런타임 페널티가 생기게 되는 단점이 있다.
  • 의존성 주입 원칙
    - 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 한다.
    - 둘 다 추상화에 의존해야 하며, 이때 추상화는 세부 사항에 의존하지 말아야 한다.

의존성 주입

 

팩토리 패턴

 

  • 팩토리 패턴(factory pattern)
    - 객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴이자 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴
    - 상위 클래스와 하위 클래스가 분리되기 때문에 느슨한 결합을 가진다.
    - 상위 클래스에서는 인스턴스 생성 방식에 대해 알 필요가 없기 때문에 더 많은 유연성을 갖는다.
    - 객체 생성 로직이 따로 떼어져 있기 때문에 코드를 리팩터링하더라도 한 곳만 고칠 수 있게 되니 유지 보수성이 증가
  • 자바스크립트의 팩토리 패턴
    - 간단하게 new Object()로 구현 가능
    - 전달받은 값에 따라 다른 객체를 생성하며 인스턴스의 타입 등을 정한다.
    - 정적 메서드를 활용하면 클래스의 인스턴스 없이 호출이 가능하여 메모리를 절약할 수 있고 개별 인스턴스에 묶이지 않으며 클래스 내의 함수를 정의할 수 있는 장점이 있다.

 

전략 패턴

 

  • 전략 패턴(strategy pattern)
    - 객체의 행위를 바꾸고 싶은 경우 직접 수정하지 않고 전략이라고 부르는 캡슐화한 알고리즘을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴이다.

    - 정책 패턴(policy pattern)이라고도 한다.
  • passport의 전략 패턴
    - 전략 패턴을 활용한 라이브러리
    - Node.js에서 인증 모듈을 구현할 때 쓰는 미들웨어 라이브러리

 

옵저버 패턴

 

  • 옵저버 패턴(observer pattern)
    - 주체가 어떤 객체(object)의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴
    - 주체 : 객체의 상태 변화를 보고 있는 관찰자
    - 옵저버 : 이 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 '추가 변화 사항'이 생기는 객체들
    - 주체와 객체를 따로 두지 않고 상태가 변경되는 객체를 기반으로 구축하기도 한다.
    - 주로 이벤트 기반 시스템에 사용하며 MVC(Model-View-Controller) 패턴에도 사용된다.
  • 자바스크립트에서의 옵저버 패턴
    - 프록시 객체를 통해 구현 가능
    - 프록시 개체 : 어떠한 대상의 기본적인 동작(속성 접근, 할당, 순회, 열거, 함수 호출 등)의 작업을 가로챌 수 있는 객체
    - 두 개의 매개변수를 가진다.
      ▶ target : 프록시할 대상
      ▶ handler : 프록시 객체의 target 동작을 가로채서 정의할 동작들이 정해져 있는 함수
  • 프록시 객체를 이용한 옵저버 패턴
    - 프록시 객체의 get() 함수는 속성과 함수에 대한 접근을 가로챈다.
    - has() 함수는 in 연산자의 사용을 가로챈다.
    - set() 함수는 속성에 대한 접근을 가로챈다.
  • Vue.js 3.0의 옵저버 패턴
    - ref나 reactive로 정의하면 해당 값이 변경되었을 때 자동으로 DOM에 있는 값이 변경되는데, 이는 프록시 객체를 이용한 옵저버 패턴을 이용하여 구현
    - DOM(Document Object Model) : 문서 객체 모델을 의미하며, 웹 브라우저상의 화면을 이루고 있는 요소들을 지칭

 

프록시 패턴과 프록시 서버

 

  • 프록시 패턴(proxy pattern)
    - 대상 객체에 접근하기 전 그 접근에 대한 흐름을 가로체 대상 객체 앞단의 인터페이스 역할을 하는 디자인 패턴
    - 이를 통해 객체의 속성, 변환 등을 보완하며 보안, 데이터 검증, 캐싱, 로깅에 사용한다.
  • 프록시 서버(proxy server)
    - 서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램
    - 프록시 서버에서의 캐싱
      ▶ 캐시 안에 정보를 담아두고, 캐시 안에 있는 정보를 요구하는 요청에 대해 다시 저 멀리 있는 원격 서버에 요청하지 않고 캐시 안에 있는 데이터를 활용하는 것
      ▶ 이를 통해 불필요하게 외부와 연결하지 않기 때문에 트래픽을 줄일 수 있다.
    - 프록시 서버로 쓰는 nginx
      ▶ nginx는 비동기 이벤트 기반의 구조와 다수 연결을 효과적으로 처리 가능한 웹 서버
      ▶ 주로 Node.js 서버 앞단의 프록시 서버로 활용
      ▶ Node.js 서버를 구축할 때 앞단에 nginx를 둔다.
      ▶ 이를 통해 익명의 사용자의 직접적인 서버로의 접근을 차단하고 간접적으로 한 단계 더 거침으로써 보안성을 강화한다.
    - 버퍼 오버플로우 : 버퍼는 보통 데이터가 저장되는 메모리 공간으로, 메모리 공간을 벗어나는 경우이다. 이때 사용되지 않아야 할 영역에 데이터가 덮어씌워져 주소, 값을 바꾸는 공격이 발생하기도 한다.
    - gzip 압축 : LZ77과 Huffman 코딩의 조합인 DEFLATE 알고리즘을 기반으로 한 압축 기술
    - 프록시 서버로 쓰는 CloudFare
      ▶ 전 세계적으로 분산된 서버가 있고 이를 통해 어떠한 시스템의 콘텐츠 전달을 빠르게 할 수 있는 CDN 서비스이다.
      ▶ CDN(Contents Delivery Network) : 각 사용자가 인터넷에 접속하는 곳과 가까운 곳에서 콘텐츠를 캐싱 또는 배포하는 서버 네트워크를 말한다. 이를 통해 사용자가 웹 서버로부터 콘텐츠를 다운로드하는 시간을 줄일 수 있다.
    - CORS와 프런트엔드의 프록시 서버
      ▶ CORS(Cross-Origin Resource Sharing) : 서버가 웹 브라우저에서 리소스를 로드할 때 다른 오리진을 통해 로드하지 못하게 하는 HTTP 헤더 기반 메커니즘
      ▶ 프런트엔드 서버를 만들어서 백엔드 서버와 통신할 때 주로 CORS 에러를 마주치는데, 이를 해결하기 위해 프런트엔드에서 프록시 서버를 만들기도 한다.

 

이터레이터 패턴

 

  • 이터레이터 패턴(iterator pattern) : 이터레이터를 사용하여 컬렉션의 요소들에 접근하는 디자인 패턴
  • 순회할 수 있는 여러 가지 자료형의 구조와는 상관없이 이터레이터라는 하나의 인터페이스로 순회가 가능
728x90
Comments