r잡초처럼
바른 프로그래밍
r잡초처럼
전체 방문자
오늘
어제
  • 분류 전체보기 (124)
    • FastAPI (7)
    • 끄적끄적 (2)
    • Python (17)
    • Django (31)
    • Database (2)
    • Docker (7)
    • 디자인패턴 (2)
    • CS 공부 (12)
      • 알고리즘 (2)
      • 자료 구조 (1)
      • 네트워크 (7)
      • IT 지식 (1)
      • 운영체제 (1)
    • 기타 팁들 (10)
    • Aws (2)
    • 독서 (1)
    • 코딩테스트 공부 (1)
      • 백준 (0)
      • 프로그래머스 (1)
    • DevOps (13)
    • TIL (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • validate
  • encoding
  • 전기 신호
  • pycharm
  • 랜과 왠
  • docker
  • 컴퓨터 기본 지식
  • fastapi
  • 네트워크
  • Batch
  • CS 지식
  • 7장
  • 케이블의 종류
  • 상속 안티 패턴
  • preonboarding
  • 5장 회사에서 하는 랜 구성
  • 물리 계층
  • 모두의 네트워크
  • dotenv
  • 완벽한 IT 인프라 구축을 위한 Docker
  • query param
  • 파이썬 클린 코드
  • pytest
  • 랜 카드
  • 책 리뷰
  • 상속과 컴포지션
  • poetry
  • cp949
  • 6장
  • depends

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
r잡초처럼

바른 프로그래밍

Python

상속 안티 패턴

2023. 9. 5. 00:29

원하는 데이터 객체를 만들기 위해 많은 비용을 들이지 말자. 다음 예를 보자

class TransactionalPolicy(collections.UserDict):
    """잘못된 상속의 예"""
    
    def change_in_policy(self, customer_id, **new_policy_data):
    	self[customer_id].update(**new_policy_data)

이 클래스는 고객의 정책에 접근해 정책을 바꾼다는 목적에는 부합할 수 있으나,  상속의 안티패턴을 보여주고 있다. 

  1. 계층 구조가 잘못됐다.

    기본 클래스에서 새 클래스를 만드는 것은 개념적으로 확장되고 세부적인 것이다라는 것을 뜻한다. 하지만 해당 데이터 객체는 Dict를 상속하면서 Dict의 개념을 확장했다기 보단 필요한 몇몇 부분(고객 데이터를 접근하는 부분)만 사용했다는 느낌을 가지게 된다.

  2. 결합력이 강하다.

    이 클래스에는 pop() 또는 items()와 같은 메서드가 필요하지 않지만 포함되어 있다. 덕타이핑으로 볼 때 해당 오리는 필요없는 부위가 있는 이상한 오리다.

이것이 구현 객체를 도메인 객체와 혼합할 때 발생하는 문제이다. dict는 특정 유형의 작업에 적합한 객체 또는 데이터 구조로서 다른 데이터 구조와 마찬가지로 트레이드오프가 있다. TransactionPolicy는 특정 도메인의 정보를 나타내는 것이므로 해결하려는 문제의 일부분에 사용되는 엔티티여야 한다.

 

올바른 해결책은 컴포지션을 사용하는 것이다.

컴포지션이란?
다른 클래스의 인스턴스를 자신의 인스턴스 변수로 가지고 있는 것이다.
class TransactionalPolicy:
    """컴포지션을 사용한 리팩토링 예제"""
    
    def __init__(self, policy_data, **extra_data):
        self._data = {**policy_data, **extra_data}
        
    def change_in_policy(self, customer_id, **new_policy_data):
        self._data[customer_id].update(**new_policy_data)
        
    def __getitem__(self, customer_id):
    	return self._data[customer_id]
        
    def __len__(self):
    	return len(self._data)

이 방법은 개념적으로 정확할 뿐만 아니라 확장성도 뛰어나다.

'Python' 카테고리의 다른 글

가상파일시스템 pyfakefs 를 통해 테스트 코드 작성하기  (0) 2023.04.24
Poweshell 환경에서 poetry 와 pyenv로 가상환경 세팅하기  (0) 2023.03.15
스택프레임, 빅오  (0) 2023.03.01
결합과 추상화 - 3  (0) 2023.02.21
결합과 추상화 - 2  (0) 2023.02.13
    'Python' 카테고리의 다른 글
    • 가상파일시스템 pyfakefs 를 통해 테스트 코드 작성하기
    • Poweshell 환경에서 poetry 와 pyenv로 가상환경 세팅하기
    • 스택프레임, 빅오
    • 결합과 추상화 - 3
    r잡초처럼
    r잡초처럼
    오늘보다 내일 더 나은 개발자가 되기 위한 노력을 기록하는 블로그 입니다.

    티스토리툴바