일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- gRPC
- 결제서비스
- 디버깅
- 코드 계약
- 검색어 추천
- 프로그래머스
- prg 패턴
- 수신자 대상 다르게
- 객체지향패러다임
- AWS
- BFS
- piplining
- 이분탐색
- 카카오
- 깊게 생각해보기
- jwt 표준
- 좋은 코드 나쁜 코드
- 백준
- 셀러리
- 레디스 동시성
- 숫자 블록
- 쿠키
- 트랜잭샨
- spring event
- 알람 시스템
- 구현
- 누적합
- branch 전략
- 완전탐색
- docker
- Today
- Total
코딩관계론
코드 계약 본문
[코드 계약의 목적]
- 일관성과 명확성: 코드 계약을 통해 코드의 의도와 사용 방법을 명확하게 정의할 수 있습니다. 이는 코드를 작성한 개발자뿐만 아니라 다른 사람들에게도 코드의 의미를 명확히 전달하여 일관성 있는 개발을 도와줍니다.
- 문서화와 이해도: 코드 계약은 코드에 대한 문서화 역할을 수행합니다. 이를 통해 코드를 이해하기 쉽고, 코드의 목적과 기능을 파악할 수 있습니다. 코드 계약을 통해 다른 개발자들이 코드를 빠르게 이해하고 활용할 수 있습니다.
- 협업과 유지 보수: 코드 계약은 다른 개발자와의 협업에서 필요한 코드 사용법을 명확하게 전달합니다. 이를 통해 다른 개발자들은 코드를 쉽게 활용하고 유지 보수할 수 있습니다. 코드 계약은 프로젝트의 지속적인 개발과 유지 관리를 지원합니다.
- 버그와 오류 예방: 코드 계약은 코드의 선결 조건과 사후 조건을 명시함으로써 코드의 안정성을 향상시킵니다. 이를 통해 잠재적인 버그와 오류를 사전에 예방하고 코드의 신뢰성을 높일 수 있습니다.
코드 계약을 통해 우리는 다른 사람들과 협업하면서 코드를 만들어가고 다른 분이 작성한 코드를 사용하거나, 내가 작성한 코드를 다른 분들이 사용할 수 있는 고품질 코드라는 목표 달성이 가능하다.
[코드 계약의 패러다임]
용어 설명
1. 선결 조건: 코드를 호출하기 전에 사실이어야 하는 것
2 사후 조건: 코드가 호출된 후에 사실이어야 하는 것
3. 불변 사항:코드가 호출되기 전과 후에 시스템 상태를 비교해서 변경되지 않아야 하는 사항
1. 계약에 의한 프로그래밍 (Contract Programming)
계약에 의한 프로그래밍은 함수 또는 모듈 간의 계약을 명시적으로 정의하고 준수하는 프로그래밍 방법입니다. 이 방법은 함수의 입력과 출력, 그리고 함수의 실행 전후에 유지되어야 하는 사전조건과 사후조건을 명시적으로 정의하여 프로그램의 일관성과 신뢰성을 높이는 데 초점을 둡니다.
계약에 의한 프로그래밍은 코드 간의 상호 작용을 마치 계약처럼 간주하며, 각 함수나 모듈이 계약을 준수해야만 정상적으로 동작할 수 있습니다
계약에 의한 프로그래밍 (Contract Programming)
def divide(a, b):
"""두 수를 나누는 함수"""
# 사전조건: b는 0이 아니어야 함
assert b != 0, "두 번째 인자는 0이 아니어야 합니다."
# 사후조건: 반환값은 a를 b로 나눈 값이어야 함
result = a / b
assert result * b == a, "나눗셈 결과가 정확하지 않습니다."
return result
2. 계약에 의한 디자인 (Contract-based Design)
계약에 의한 디자인은 소프트웨어 시스템의 설계 단계에서 계약을 기반으로 시스템을 구성하는 방법입니다. 이 방법은 시스템의 구성 요소 간의 계약을 정의하여 각 구성 요소가 기대되는 동작과 상호 작용을 준수해야 함을 명시합니다.
계약에 의한 디자인은 시스템의 일관성과 유연성을 향상시키며, 다른 개발자들이 시스템을 이해하고 확장할 수 있도록 돕는 역할을 합니다. 계약에 의한 디자인은 클래스나 모듈 간의 인터페이스를 계약으로 정의하고, 이를 준수하는 구현체를 작성함으로써 시스템의 일관성을 유지합니다.
계약에 의한 디자인 예시
class Calculator:
"""계산기 클래스"""
def add(self, a, b):
"""두 수를 더하는 메서드"""
# 계약: a와 b는 숫자여야 함
assert isinstance(a, (int, float)), "첫 번째 인자는 숫자여야 합니다."
assert isinstance(b, (int, float)), "두 번째 인자는 숫자여야 합니다."
return a + b
def subtract(self, a, b):
"""두 수를 빼는 메서드"""
# 계약: a와 b는 숫자여야 함
assert isinstance(a, (int, float)), "첫 번째 인자는 숫자여야 합니다."
assert isinstance(b, (int, float)), "두 번째 인자는 숫자여야 합니다."
return a - b
[공개 사항 vs 세부 사항]
1. 공개 사항
- 함수와 클래스 이름: 호출하는 쪽에서 이것을 모르면 사용할 수 없기 때문입니다
- 인자 유형: 인자 유형이 틀리면 컴파일 되지 않는다
- 반환 유형: 호출하는 쪽에서 함수의 반환 유형을 알아야 한다. 이 유형과 일치하지 않는 유형을 사용하면 코드는 컴파일되지 않는다
- 검사 예외: 호출하는 코드가 이것을 처리하지 않으면 코드는 컴파일 되지 않는다
[예시]
def calculate_average(numbers: List[float]) -> float:
"""주어진 숫자들의 평균을 계산하는 함수"""
assert isinstance(numbers, list), "인자는 리스트여야 합니다."
assert all(isinstance(num, (int, float)) for num in numbers), "리스트의 원소는 숫자여야 합니다."
assert len(numbers) > 0, "리스트는 비어있으면 안됩니다."
total = sum(numbers)
average = total / len(numbers)
return average
2. 세부 사항
- 주석문과 문서는 실제 사용자가 잘 읽지 않을 확률이 매우 높습니다. 따라서 세부 사항을 주석문이나 문서로 상세하게 기술하는 것은 비효율적입니다.
- 비검사 예외 (Unchecked Exceptions)는 계약에 포함되지 않는 예외입니다. 일반적으로 검사 예외 (Checked Exceptions)는 계약의 일부로서 명시되고 처리되어야 하지만, 비검사 예외는 계약에 명시되지 않으며 명시적으로 처리할 필요가 없는 예외입니다. 비검사 예외는 예외 처리의 부담을 줄이고 코드의 간결성을 유지하기 위해 사용될 수 있습니다.
- 세부 사항은 주석문과 문서화로 구성되며, 최대한 사용을 자제해야 합니다
[예시]
class UserSettings:
"""사용자 세팅 클래스"""
def __init__(self):
"""사용자 세팅 초기화"""
self._username = ""
self._email = ""
self._notifications_enabled = False
def set_username(self, username: str):
"""사용자명 설정
Args:
username (str): 사용자명
Precondition:
- `set_email` 메서드가 호출된 이후에 호출되어야 함
"""
def set_email(self, email: str):
"""이메일 설정"""
# ...
pass
'Clean code' 카테고리의 다른 글
코드를 오용하게 어렵게 만들라 (0) | 2023.07.10 |
---|---|
오류 (0) | 2023.05.20 |
코드 추상화 (0) | 2023.05.15 |
파이썬 데코레이터(Decorator) (0) | 2023.02.26 |
[Clean code] 클래스 (0) | 2023.01.11 |