파이썬 디자인 패턴 - 01

2019-02-06

대학교 수업시간에 교수님이 이렇게 말했다.

디자인 패턴은 개발에 재능이 없는 너를 위한 방법론이다. 23가지의 패턴만 달달 외운다면 아무리 재능이 없는 너라도 대부분의 문제는 해결할 수 있다.

교수님의 말을 100% 신뢰하진 않았지만, 그 이후로 나에게 디자인 패턴 은 만병통치약 또는 치트키와 같은 개념으로 생각해 왔다.

당연하게도 나는 생각만 하고 공부는 안했다. 우연히 서점에서 이 책을 보게 되었고 이쁜 표지와 저렴한 가격 그리고 얇은 두께 가 마음에 들었다. 책은 파이썬으로 구성되어 있지만 별로 상관 없을것 같아 바로 결제했다.

설 연휴에 SQL 책을 더 읽으려 했지만 회사에 두고와서 이 책을 읽기 시작했다. 얼른 다 읽고 마무리 했으면 좋겠다.

1장. 개요

1장은 OOP의 기본개념과 원리에 대한 설명이 주를 이뤘다.

객체지향 프로그래밍

‘파이썬의 모든것은 객체다’라는 말이 있듯이 파이썬의 클래스 인스턴스와 변수는 개별적인 메모리 공간에 저장된다.

- 객체

객체는 다음과 같은 특성이 있다.

  • 프로그램 내의 개체(Entitiy)를 나타낸다
  • 개체는 다른 개체와 상호작용하며 목적을 달성한다.
  • Ex ) Person과 Car는 각각 개체다. Person은 Car를 타고 원하는 위치로 이동한다

- 클래스

클래스를 사용해 특정 개체를 표현.

  • 클래스는 속성과 행동을 포함하는 객체를 정의한다. 속성은 데이터의 요소, 함수는 특정 작업을 수행
  • 객체 초기 상태를 설정하는 생성자가 있다.
  • 템플릿으로 쉽게 재사용 가능

- 메소드

메소드의 역할은 다음과 같다.

  • 객체의 행위를 나타낸다.
  • 속성을 조작하고 작업을 수행한다.

객체지향 프로그래밍의 주요 기능

- 캡슐화

  • 객체의 기능과 상태 정보를 외부로부터 은닉한다.
  • 클라이언트는 직접 객체 내부 구조 및 상태를 수정할수 없다. getter, setter를 통해 내부 상태를 변경한다.
  • 파이썬은 public, private, protected 같은 접근 제어 키워드가 없다. __를 붙여 접근제어를 한다.

- 다형성

  • 다형성에는 두 가지 의미가 있다.
    • 객체는 함수 인자에 따라 다른 기능을 한다. (오버로딩)
    • 동일한 인터페이스를 여러 형식의 객체들이 공유한다.
  • 파이썬은 다형성을 지원.
    • Ex) ‘ + ‘ 연산자는 두 정수를 더하거나 문자열을 합칠 때 모두 사용 가능하다.

- 상속

  • 상속이란 클래스의 기능이 부모 클래스로부터 파생되는 것을 일컫는다.
  • 부모 클래스에서 정의된 함수를 재사용할 수 있고 애플리케이션의 기본 기능을 확장한다.
  • 파이썬은 자바와 다르게 다중 상속을 지원한다.

- 추상화

  • 클라이언트가 클래스 객체를 생성하고 인터페이스에 정의된 함수를 호출할 수 있는 인터페이스를 제공한다.
  • 클라이언트는 클래스의 복잡한 내구 구현에 대한 이해없이 간편하게 인터페이스를 사용할 수 있다.

- 컴포지션

  • 객체나 클래스를 더 복잡한 자료 구조나 모듈로 묶는 행위.
  • 컴푖션을 통해 특정 객체는 다른 모듈의 함수를 호출할 수 있다. 즉 상속 없이 외부 기능을 사용할 수 있다.

객체지향 디자인의 기본 원칙

- 개방-폐쇄 원칙

클래스와 객체, 메소드 모두 확장엔 개방적이고 수정엔 폐쇄적이어야 한다는 원칙이다.

클래스나 모듈의 기능을 확장하더라도 기본 클래스는 수정하지 않도록 설계해야 한다. 클래스의 확장만으로 새로운 기능을 구현할 수 있어야 한다.

  • 장점
    • 기본 클래스를 수정하지 않기 때문에 실수가 줄어든다.
    • 기존 코드의 호환성을 보장한다.

- 제어 반전 원칙

상위 모듈은 하위 모듈에 의존적이지 않아야 한다는 원칙이다. 세부 구현이 추상화에 의존해야 한다. 추상화가 세부사항에 의존하는 상황은 바람직 하지 않다.

클래스의 세부 내용은 추상화한다. 반대로 추상화가 세부 사항에 의존하는 구조는 피해야 한다.

  • 장점
    • 모듈 간의 낮은 상호 의존도는 시스템 복잡도를 줄인다.
    • 관련 모듈을 연결하는 추상화 계층 덕분에 모듈 간 상호 관계를 쉽게 관리할 수 있다.

- 인터페이스 분리 원칙

클라이언트는 불필요한 인터페이스에 의존하지 않아야 한다는 원칙이다.

개발자는 반드시 해당 기능과 관련 있는 메소드만을 작성해야 한다.

  • 장점
    • 인터페이스에 특화된 메소드만 있는 가벼운 인터페이스를 작성하게 된다.
    • 의도하지 않은 메소드로 인터페이스가 채워지지 않도록 한다.

- 단일 책임 원칙

클래스는 하나의 책임만을 가져야 한다는 원칙이다.

두 가지 이상의 기능이 필요하다면 클래스를 나눠야 한다. 클래스를 수정하는 이유가 특정 기능 때문이라면 괜찮지만 두 가지 이상의 이유 때문이라면 클래스 자체를 나눠야 한다.

  • 장점
    • 특정 기능을 수정할 때 관련 클래스 외에는 건드릴 필요가 없다.
    • 한 개의 클래스에 여러 가지 기능이 있다면 관련된 모든 클래스를 수정해야 하는 상황이 발생할 수 있다.

- 치환 원칙

상속 받는 클래스는 기본 클래스의 역할을 완전히 치환할 수 있어야 한다는 원칙이다.

파생된 클래스는 기본 클래스를 와넞ㄴ히 확장해야 한다는 이야기다. 코드 수정 또는 추가 없이도 파생된 클래스는 기본 클래스를 대체할 수 있어야 한다.

디자인 패턴의 개념

디자인 패턴은 GoF가 문제 해결책으로 처음 제시한 개념이다. 총 23개의 디자인 패턴을 소개하며 자바 기반으로 한다. 디자인 패턴이라는 개념은 발명 보다 발견 에 가깝다.

  • 주요 기능
    • 언어에 독립적이며 모든 프로그래밍 언어에 적용할 수 있다.
    • 새로운 패턴이 아직도 연구되고 있다.
    • 목적에 따라 변경될 수 있어 개발에 유용하다.

디자인 패턴은 이미 알려진 문제의 해결책이다

  • 디자인 패턴 장점
    • 여러 프로젝트에서 재사용 가능
    • 설계 문제를 해결할 수 있다.
    • 오랜 시간에 걸쳐 유효성이 입증됐다.
    • 신뢰할 수 있는 솔루션이다.

- 디자인 패턴 용어

아무 코드나 디자인을 디자인 패턴으로 분류할 수 없다. 문제를 해결할 때 사용하는 구조체나 자료구조를 패턴이라고 부르지 않는다.

  • 스니펫
    • 데이터베이스에 연결하는 파이썬 코드 등의 특수한 목적을 위한 코드
  • 디자인
    • 문제에 대한 해결책
  • 스탠다드
    • 문제를 해결하는 대표적인 방식
  • 패턴
    • 유효성이 검증된 효율적이고 확장 가능한 해결책

- 디자인 패턴 맥락

디자인 패턴을 효율저긍로 사용하려면 개발자는 애플리케이션의 전체 맥락을 정확히 이해해야 한다.

  • 참가자
    • 디자인 패턴에서 사용되는 클래스를 일컫는다. 각 클래스는 다른 역할을 한다.
  • 비기능적 조건
    • 메모리 최적화와 사용성, 성능 등이 여기에 속한다. 솔루션 전체에 영향을 미치는 핵심적인 요소
  • 타협선
    • 디자인 패턴이 모든 상황에 딱 들어 맞지 않으므로 적당한 타협선이 필요하다
  • 결과
    • 디자인 패턴이 적합하지 않은 상황에서 사용한다면 결과가 좋지 않은 경우가 있다. 개발자는 디자인 패턴의 영향과 사용법을 정확히 인지해야 한다.

디자인 패턴의 분류

GoF 채겡서 23개의 디자인 패턴을 3개의 범주로 분류한다.

  • 생성 패턴
  • 구조 패턴
  • 행위 패턴

- 생성 패턴

  • 객체가 생성되는 방식을 중시
  • 객체 생성 관련 상세 로직을 숨김
  • 코드는 생성하려는 객체형과는 독립적이다.

싱글톤 패턴은 생성 패턴의 한 종류다

- 구조 패턴

  • 클래스와 객체를 더 큰 결과물로 하빌 수 있는 구조로 설계한다.
  • 구조를 간결화하고 클래스와 객체 간의 상호관계를 파악할 수 있다.
  • 클래스 상속과 컴포지션을 중시한다.

어댑터 패턴은 구조 패턴의 한 종류다.

- 행위 패턴

  • 객체 간의 상호작용과 책임을 중시
  • 객체는 상호작용하지만 느슨하게 결합돼야 한다.

옵저버 패턴은 행위 패턴의 한 종류다