[CS-009][중급] 객체와 함수로 장바구니 만들기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[CS-009][중급] 객체와 함수로 장바구니 만들기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 123회 작성일 26-09-03 21:36

본문

[이번 수업]

같은 장바구니 문제를 객체지향과 함수형이라는 두 가지 사고법으로 풀어봅니다. 프로그래밍 패러다임은 문제와 코드를 바라보고 나누는 방식입니다. 어느 한쪽이 항상 정답은 아닙니다. 상태와 규칙이 중요한 경우와, 입력에서 새 결과를 계산하는 흐름이 중요한 경우의 차이를 확인합니다.

[선수지식]

함수 호출, 클래스와 인스턴스, 리스트와 튜플을 알고 있으면 좋습니다. 튜플은 만든 뒤 항목을 직접 바꾸지 않는 값 모음입니다.

[학습목표]

1. 객체지향에서 데이터와 동작을 한 객체에 묶는 이유를 설명합니다.
2. 함수형에서 순수 함수와 바꾸지 않는 값을 선호하는 이유를 설명합니다.
3. 문제의 성격에 따라 두 방식을 선택하거나 섞을 수 있습니다.

[핵심개념]

객체지향은 관련 데이터와 기능을 객체에 함께 둡니다. 객체는 상태를 기억하고 메서드로 그 상태를 바꿀 수 있습니다. 예를 들어 Cart가 상품 목록을 보관하고 add가 목록을 변경합니다. 캡슐화는 내부 상태와 규칙을 한 경계 안에 두고 정해진 메서드로 다루게 하는 설계입니다. 주문처럼 수명과 규칙이 있는 대상을 표현하기 좋습니다.

함수형은 값을 함수에 넣어 새 값을 얻는 흐름에 집중합니다. 순수 함수는 같은 입력에 같은 출력을 내고 바깥 상태를 몰래 바꾸지 않습니다. 부수 효과는 파일 저장, 화면 출력, 네트워크 요청처럼 계산 밖의 상태를 바꾸는 일입니다. 이를 경계로 모으면 계산을 시험하고 조합하기 쉽습니다. 함수형 코드는 기존 값을 직접 바꾸기보다 새 값을 반환하는 방식을 선호합니다. Python은 두 방식을 모두 지원하므로 계산은 순수 함수로, 입출력이나 긴 수명은 객체로 맡길 수도 있습니다.

[따라하기]

아래 내용을 paradigm_demo.py로 저장합니다.

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class Item:
    name: str
    price: int

class Cart:
    def __init__(self):
        self._items = []

    def add(self, item):
        if item.price < 0:
            raise ValueError("price must be non-negative")
        self._items.append(item)

    def total(self):
        return sum(item.price for item in self._items)

def add_item(items, item):
    if item.price < 0:
        raise ValueError("price must be non-negative")
    return items + (item,)

def total(items):
    return sum(item.price for item in items)

book = Item("book", 12000)
pen = Item("pen", 3000)

oop_cart = Cart()
oop_cart.add(book)
oop_cart.add(pen)

empty_cart = ()
fp_cart = add_item(empty_cart, book)
fp_cart = add_item(fp_cart, pen)

print(f"OOP total={oop_cart.total()}")
print(f"FP total={total(fp_cart)}")
print(f"empty cart size={len(empty_cart)}")
```

Windows는 `py paradigm_demo.py`, macOS와 Linux는 `python3 paradigm_demo.py`로 실행합니다. 예상 결과입니다.

```text
OOP total=15000
FP total=15000
empty cart size=0
```

객체 방식은 add가 내부 목록을 바꿉니다. 함수 방식은 새 튜플을 반환하므로 empty_cart는 그대로 비어 있습니다. `frozen=True`는 Item 필드의 대입을 막지만 보안 기능이나 완전한 불변성을 뜻하지 않습니다.

[흔한 실수]

모든 기능을 클래스로 만들거나 람다만 쓰면 함수형이라고 생각하기 쉽습니다. 상속을 억지로 늘리면 관계가 복잡해지고, 순수 함수 안에서 전역 목록을 바꾸면 동작을 이해하기 어렵습니다. 큰 데이터를 매번 복사하면 비용이 커질 수 있으므로 성능도 측정합니다.

[보안 주의]

예제는 본인 소유의 로컬 환경에서만 실행합니다. 실제 서비스는 가격의 범위와 자료형도 검사해야 합니다. 비밀번호나 토큰을 객체 필드에 넣고 객체 전체를 로그로 출력하지 마세요. `frozen=True`는 값을 암호화하지 않습니다. 외부 입력은 파일·네트워크 같은 경계에서 검증합니다.

[직접 해볼 과제]

Cart에 마지막 상품을 제거하는 remove_last 메서드를 추가하세요. 함수 방식에는 원래 튜플을 바꾸지 않고 할인 합계를 반환하는 `discounted_total(items, percent)`를 추가합니다. 할인 전후 값과 두 튜플의 항목 수를 출력해 원본이 유지되는지 확인하세요.

[확인문제]

1. Cart의 add 메서드를 호출하면 어느 상태가 바뀌나요?
2. add_item이 기존 튜플 대신 새 튜플을 반환하는 장점은 무엇인가요?
3. 파일 저장 같은 부수 효과를 계산 함수와 분리하면 무엇이 쉬워지나요?

[다음 학습]

다음은 TOOL-009 환경변수와 설정 파일입니다. 코드와 실행 환경의 값을 분리하고 비밀값을 안전하게 다루는 원칙을 익힙니다.

[공식 참고 자료]

Python 클래스 튜토리얼
https://docs.python.org/3/tutorial/classes.html

Python 함수형 프로그래밍 HOWTO
https://docs.python.org/3/howto/functional.html

Python dataclasses 공식 문서
https://docs.python.org/3/library/dataclasses.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
1,045
어제
5,103
최대
16,772
전체
772,099
Copyright © 소유하신 도메인. All rights reserved.