디자인 패턴

imeline·2024년 2월 5일
  • 디자인 패턴 : 프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 구약 형태로 만들어 놓은 것을 의미

싱글톤 패턴

  • 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴

  • 보통 데이터베이스 연결 모듈에 많이 사용

  • 장점 : 하나의 인스턴스를 만들어 놓고 해당 인스턴스를 다른 모듈들이 공유하며 사용하기 때문에, 인스턴스를 생성할 때 드는 비용이 줄어듦

  • 단점 : 의존성이 높아짐

  • 데이터베이스 연결 모듈에 많이 쓰임

    • 하나의 인스턴스를 기반으로 new DB를 생성
      -> 데이터베이스 연결에 관한 인스턴스 생성 비용을 아낄 수 있음

싱글톤 패턴의 단점

  • 싱글톤 패턴은 TDD(Test Driven Development)를 할 때 걸림돌이 됨
    -> TDD를 할 때 단위 테스트를 주로 하는데, 단위 테스트는 테스트가 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야 함
    -> 하지만 싱글톤 패턴은 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴이므로, 각 테스트마다 '독립적인' 인스턴스를 만들기가 어려움

의존성 주입

  • 싱글톤 패턴은 사용하기가 쉽고 굉장히 실용적이지만, 모듈 간의 결합을 강하게 만들 수 있다는 단점이 있음
    -> 이때 의존성 주입(DI, Dependency Injection)을 통해, 모듈 간의 결합을 조금 더 느슨하게 만들어 해결할 수 있음
    + 참고로 의존성이란 종속성이라고도 하며, A가 B에 의존성이 있다는 것은 B의 변경 사항에 대해 A 또한 변해야 된다는 것을 의미

  • 그림처럼 메인 모듈이 직접 다른 하위 모듈에 대한 의존성을 주기보다는
    중간에 의존성 주입자가 이 부분을 가로채, 메인 모듈이 간접적으로 의존성을 주입하는 방식
    -> 이를 통해 메인 모듈(상위 모듈)은 하위 모듈에 대한 의존성이 떨어지게 됨
    -> 이를 '디커플링이 된다'고도 함

의존성 주입의 장점

  • 모듈들을 쉽게 교체할 수 있는 구조가 되어, 테스팅하기 쉽고 마이그레이션(다른 시스템으로 이동)하기도 수월
  • 구현할 때 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어 주기 때문에
    -> 애플리케이션 의존성 방향이 일관되고,
    -> 애플리케이션을 쉽게 추론할 수 있으며,
    -> 모듈 간의 관계들이 조금 더 명확해짐

의존성 주입의 단점

  • 모듈들이 더욱더 분리되므로 클래스 수가 늘어나, 복잡성이 증가될 수 있으며 약간의 런타임 페널티가 생기기도 함

의존성 주입 원칙

  • 의존성 주입은 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 함
  • 둘 다 추상화에 의존해야 하며, 이때 추상화는 세부 사항에 의존하지 말아야 함

팩토리 패턴

  • 객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴
  • 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴
  • 상위 클래스와 하위 클래스가 분리되기 때문에 느슨한 결합을 가짐
  • 상위 클래스에서는 인스턴스 생성 방식에 대해 전혀 알 필요가 없기 때문에 더 많은 유연성을 갖게 됨
  • 객체 생성 로직이 따로 떼어져 있기 때문에 코드를 리팩터링하더라도 한 곳만 고 칠 수 있게 되니 유지 보수성이 증가
    • 예를 들어 라떼 레시피와 아메리카노 레시피, 우유 레시피라는 구체적인 내용이 들어 있는 하위 클래스가 컨베이어 벨트를 통해 전달되고, 상위 클래스인 바리스타 공장에서 이 레시피들을 토대로 우유 등을 생산하는 생산 공정
    • 이는 의존성 주입이라고도 볼 수 있음
      -> Coffeeractory에서 LatteFactory의 인스턴스를 생성하는 것이 아닌 Lattefactory에서 생성한 인스턴스를 CoffeeFactory에 주입하고 있기 때문

전략 패턴

  • 정책 패턴이라고도 함
  • 객체의 행위를 바꾸고 싶은 경우, '직접' 수정하지 않고 전략이라고 부르는 '캡슐화한 알고리즘'을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴
  • 예를 들어, 우리가 어떤 것을 살 때 네이버페이, 카카오페이 등 다양한 방법으로 결제하듯이 전략만 바꾸어 결제를 하게끔 하는 것

옵저버 패턴

  • 주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다, 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려 주는 디자인 패턴

    • 여기서 주체란 객체의 상태 변화를 보고 있는 관찰자이며, 옵저버들이란 이 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 추가 변화 사항이 생기는 객체들을 의미
    • 주제와 개체를 따로 두지 않고 상태가 변경되는 객체를 기반으로 구축하기도 함
  • 옵저버 패턴을 활용한 서비스로는 트위터가 있음
    -> 내가 어떤 사람인 주제를 팔로우 했다면, 주체가 포스팅을 올리게 되면 알림이 팔로워에게 감

  • 옵저버 패턴은 주로 이벤트 기반 시스템에 사용하며 MVC 패턴에도 사용됨

    -> 주체라고 볼 수 있는 모델에서 변경 사항이 생겨, update() 메서드로 옵저버인 뷰에 알려주고, 이를 기반으로 컨트롤러 등이 작동하는 것

옵저버 패턴 장점

  • Subject의 상태 변경을 주기적으로 조회하지 않고 자동으로 감지할 수 있다.
  • 발행자의 코드를 변경하지 않고도 새 구독자 클래스를 도입할 수 있어 개방 폐쇄 원칙(OCP)Visit Website 준수한다
  • 런타임 시점에서에 발행자와 구독 알림 관계를 맺을 수 있다.
  • 상태를 변경하는 객체(Subject)와 변경을 감지하는 객체(Observer)의 관계를 느슨하게 유지할 수 있다. (느슨한 결합)

옵저버 패턴 단점

  • 구독자는 알림 순서를 제어할수 없고, 무작위 순서로 알림을 받음
    • 하드 코딩으로 구현할수는 있겠지만, 복잡성과 결합성만 높아지기 때문에 추천되지는 않는 방법이다.
  • 옵저버 패턴을 자주 구성하면 구조와 동작을 알아보기 힘들어져 코드 복잡도가 증가한다.
  • 다수의 옵저버 객체를 등록 이후 해지하지 않는다면 메모리 누수가 발생할 수도 있다.

프록시 패턴

  • 대상 객체(subject)에 접근하기 전 그 접근에 대한 흐름을 가 로채 대상 객체 앞단의 인터페이스 역할을 하는 디자인 패턴

  • 객체의 속성, 변환 등을 보완하며 보안, 데이터 검증, 캐싱, 로깅에 사용

    • 프록시 서버에서의 캐싱 : 캐시 안에 정보를 담아두고, 캐시 안에 있는 정보를 요구하는 요청에 대해 다시 저 멀리 있는 원격 서버에 요청 하지 않고 캐시 안에 있는 데이터를 활용하는 것을 말한다. 이를 통해 불필요하게 외부와 연결하지 않기 때문에 트래픽을 줄일 수 있다는 장점이 있다.
  • 프록시 객체로 쓰이기도 하지만, 프록시 서버로도 활용

  • 프록시 패턴 추가 설명 사이트

프록시 서버

  • 서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램

프록시 서버로 쓰는 nginx

  • nginx는 비동기 이벤트 기반의 구조와 다수의 연결을 효과적으로 처리 가능한 웹 서버

  • 주로 Node.js 서버 앞단의 프록시 서버로 활용

  • Node.js의 버퍼 오버플로우 취약점을 예방하기 위해서는, nginx를 프록시 서버로 앞단에 놓고 Node.js를 뒤쪽에 놓는 것이 좋음
    -> 익명 사용자의 직접적인 서버로의 접근을 차단하고, 간접적으로 한 단계를 더 거침으로써 보안성을 더욱 강화할 수 있음

    • 버퍼 오버플로우 : 버퍼는 보통 데이터가 저장되는 메모리 공간으로, 메모리 공간을 벗어나는 경우를 말한다. 이때 사용되지 않아야 할 영역에 데이터가 덮어씌워져 주소, 값을 바꾸는 공격이 발생하기도 한다.
  • 그림처럼 nginx를 프록시 서버로 둬서 실제 포트를 숨길 수 있고, 정적 자원을 grip 압축하거나, 메인 서버 앞단에서의 로깅을 할 수도 있음

프록시 서버로 쓰는 CloudFlare

  • CloudFlare는 전 세계적으로 분산된 서버가 있고 이를 통해 어떠한 시스템의 콘텐츠 전달 을 빠르게 할 수 있는 CDN 서비스
    • CDN : 각 사용자가 인터넷에 접속하는 곳과 가까운 곳에서 콘텐츠를 캐싱 또는 배포하는 서버 네트워크를 말한다. 이를 통해 사용자가 웹 서버로부터 콘텐츠를 다운로드하는 시간을 줄일 수 있다.
  • DDOS 공격 방어, HTTPS 구축 가능
    -> 웹 서버 앞단에 두어 프록시 서버로 쓰기 때문에 가능한 것

  • 그림처럼 사용자, 크롤러, 공격자가 자신의 웹 사이트에 접속하게 될 텐데, 이때 CloudFlare를 통해 공격자로부터 보호할 수 가능

DDOS 공격 방어

  • DDOS는 짧은 기간 동안 네트워크에 많은 요청을 보내 네트워크를 마비시켜 웹 사이트의 가용성을 방해하는 사이버 공격 유형
  • CloudFilare는 의심스러운 트래픽. 특히 사용 자가 접속하는 것이 아닌 시스템을 통해 오는 트래픽을 자동으로 차단해서 DDOS 공격으로부터 보호
  • CloudFlare의 거대한 네트워크 용량과 캐싱 전략으로, 소규모 DDOS 공격은 쉽게 막아낼 수 있으며, 이러한 공격에 대한 방화벽 대시보드도 제공

HTTPS 구축

  • 서버에서 HTTPS를 구축할 때, 인증서를 기반으로 구축할 수도 있음. 하지만 CloudFlare를 사용하면, 별도의 인증서 설치 없이 좀 더 손쉽게 HTTPS를 구축 가능

참조 : Inpa Dev 👨‍💻:티스토리, 면접을 위한 CS 전공지식 노트 (주홍철)

0개의 댓글