본문 바로가기
독서

'Head First Design Patterns'를 읽고

by graygreat 2021. 11. 30.
728x90
반응형

디자인 패턴이란?

  • 개발 세계에는 많은 문제들이 존재
  • 누군가는 이미 이러한 문제들을 해결해 놓았음
  • 코드를 재사용하는 것과 마찬가지로 경험을 재사용하는 것

스트래티지 패턴 (Strategy pattern)

구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.

  • "인터페이스에 맞춰서 프로그래밍한다." 즉, "상위 형식에 맞춰서 프로그래밍한다."

    • 다형성을 활용
    • 변수를 선언하는 클래스에서 실제 객체의 형식을 몰라도 됨
  • Fly에서도 전송 서비스들을 추상화하고 이메일, 알림톡, 문자 메시지 서비스가 이를 상속받아 구체화함으로써 유연한 서비스 선택 구현

상속보다는 구성을 활용한다.

상속의 단점

  • 캡슐화 위반

    • 상위 클래스에 따라 하위 클래스의 동작에 이상이 생길 수 있음
    • 상위 클래스의 내부 구현이 달라지면 하위 클래스를 고쳐야 할 수 있음
  • 설계가 유연하지 못함

  • 다중 상속 불가

구성(Composition)이란?

  • "A는 B이다" 보다 "A에는 B가 있다"가 나을 수 있음
  • 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 메소드를 호출하는 기법

Composition을 활용한 예

  • TargetEsService에는 TargetEsRepository가 있다

팩토리 패턴 (Factory pattern)

  • 객체 생성을 처리하는 클래스를 따로 만드는 패턴

  • 변화에 닫혀있고 확장에 열려있는 OCP 구조를 가질 수 있음

  • 간단한 팩토리 패턴은 디자인 패턴이 아님

    • 프로그래밍을 하는 데 있어서 자주 쓰이는 관용구

팩토리 메소드 패턴 (Factory method pattern)

  • 객체를 생성하기 위한 인터페이스 정의
  • 어떤 클래스의 인스턴스를 서브 클래스에서 결정하게 만듦
  • 즉, 클래스의 인스턴스를 만드는 일을 서브 클래스에게 맡기는 것

팩토리 메소드 패턴 장점

  • 객체 생성 코드를 전부 한 객체 또는 메소드에 집어넣으면 코드에서 중복되는 내용 제거 가능
  • 클라이언트 입장에서는 구체 클래스가 아닌 인터페이스만 필요
    • 유연성과 확장성이 뛰어난 코드 만들 수 있음

팩토리 패턴을 사용해도 결국 구체 클래스를 만들어야 하는 거 아닌가?

  • 객체지향에서 객체 생성은 피할 수 없는 현실
  • 이 현실을 제대로 이해하고 있다면, 생성 코드를 한곳에 모아놓고 체계적으로 관리할 수 있는 디자인을 만들어야 함

싱글톤 패턴 (Singleton pattern)

  • 특정 클래스에 대해서 객체 인스턴스가 하나만 만들어질 수 있도록 해주는 패턴

  • 스프링 컨테이너에서 매번 요청이 들어올 때마다 스프링 빈이 생성된다면 메모리 낭비가 심해짐

    • @Bean이 정의되어 있으면 스프링 컨테이너는 그 클래스에 대해 딱 한 개의 인스턴스를 만듦

자바 싱글톤 패턴 구현 방법

  1. static을 통해서 싱글톤으로 만들 객체를 1개 생성한다.
  2. static 메소드를 통해서 외부에서 생성할 수 있도록 한다.
  3. 생성자에 private 접근 지정자를 사용하여 객체 생성을 하지 못하도록 한다.

싱글톤 패턴 구현 방법에는 여러 가지가 있지만, 미리 생성해두는 방법이 가장 단순하고 안전한 방법

싱글톤 패턴 문제점

  • private 생성자를 가지고 있기 때문에 상속 불가능

    • 자기 자신만이 객체를 만들 수 있도록 private를 통해 제한
    • 상속이 불가능하고 다형성 또한 제공할 수 없음
  • 테스트하기 힘듦

    • 만들어지는 방식이 제한적이기 때문에 mock 객체 등으로 대체하기 힘듦
  • 전역 상태를 만들 수 있어서 객체지향 설계 불가

  • 객체 상태를 유지하게 설계하면 안 됨

어댑터 패턴 (Adaptor pattern)

  • 한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환
  • 어댑터를 사용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 사용 가능

옵저버 패턴 (Observer pattern)

  • 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식
  • 일대다 (one-to-many) 의존성
  • 주제와 옵저버가 느슨하게 결합되어 있는 객체 디자인

템플릿 메소드 패턴 (Template method pattern)

  • 메소드에서 알고리즘의 골격을 정의

    • 간단하게 말하면 알고리즘의 틀을 만들기 위한 것
  • 알고리즘의 구조는 그대로 유지하면서 서브 클래스에서 특정 단계를 재정의할 수 있음

스트래티지 패턴 vs 템플릿 메소드 패턴

스트래티지 패턴

  • 일련의 알고리즘 군을 정의하고 그 알고리즘들을 서로 바꿔가면서 쓸 수 있게 함
  • 상속뿐만 아니라 구성을 통해 알고리즘 구현
  • 클라이언트에서 다른 스트래티지 객체를 사용하면 알고리즘 쉽게 변경

템플릿 메소드 패턴

  • 알고리즘의 각 단계마다 다른 구현을 사용하면서도 알고리즘 구조 자체는 그대로 유지
  • 상위 클래스에 코드를 정의하게 되어 코드의 중복이 거의 없음
  • 프레임워크를 만드는 데 있어서 좋음

결론

  • 세상에는 너무나도 많은 패턴들이 존재

  • 이 모든 것을 지킬 수 있는 것이고 지켜야 하는 것일까?

    • 책에서는 항상 지켜야 하는 규칙이 아니라 우리가 지향해야 할 바를 밝히고 있는 것이라 함
  • 다양한 패턴을 그림, 코드와 함께 이해하기 쉽게 설명

  • 책의 양이 상당히 많아 짧은 시간에 읽으니 어려움

    • 적당한 기간을 잡아 스터디를 통해 학습 필요
반응형

댓글