[ DAO, DTO, VO / Python ์์ ] DAO, DTO, VO ์ ๋ํด
Python์์ DAO, DTO, VO๋? ๊ฐ๋ ๊ณผ ์์
Python์ ๋น๋กฏํ ์ฌ๋ฌ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์๋ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ๊ตฌ์กฐํํ๊ธฐ ์ํด ๋ค์ํ ๋์์ธ ํจํด๊ณผ ๊ฐ์ฒด ์ ํ์ด ์ฌ์ฉ๋ฉ๋๋ค. ํนํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํต์ ํ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ DAO(Data Access Object), DTO(Data Transfer Object), VO(Value Object)์ ๊ฐ์ ๊ฐ๋ ์ด ์์ฃผ ํ์ฉ๋ฉ๋๋ค. ๊ฐ๊ฐ์ ๊ฐ๋ ๊ณผ ํน์ง, ๊ทธ๋ฆฌ๊ณ Python์์์ ๊ตฌํ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1. DAO (Data Access Object)
DAO๋?
DAO๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ํ์ผ ๋ฑ์์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ณ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉํ๋ ๊ฐ์ฒด์ ๋๋ค. DAO๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ง์ ์ ์ธ ์ํธ์์ฉ์ ๋ด๋นํ๋ฉฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์ฝ๋์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์๋ฅผ ์ฉ์ดํ๊ฒ ํฉ๋๋ค.
DAO์ ์ญํ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๋ฐ ์ข ๋ฃ: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๊ด๋ฆฌํฉ๋๋ค.
- CRUD ์์ ๊ด๋ฆฌ: Create, Read, Update, Delete์ ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์ํํฉ๋๋ค.
- ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋ถ๋ฆฌ: ๋ฐ์ดํฐ ์ ๊ทผ ๋ก์ง์ ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ๊ด๋ฆฌ์ฑ์ ๋์ ๋๋ค.
Python์์ DAO ๊ตฌํ ์์
์๋๋ User
ํ
์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ UserDAO
ํด๋์ค์
๋๋ค. ์ด ํด๋์ค๋ SQLite๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐํ๊ณ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ฝ์
ํ๊ณ ์กฐํํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
import sqlite3
class UserDAO:
def __init__(self, db_name):
self.db_name = db_name
def connect(self):
return sqlite3.connect(self.db_name)
def create_table(self):
with self.connect() as conn:
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER
)
''')
conn.commit()
def insert_user(self, name, age):
with self.connect() as conn:
cursor = conn.cursor()
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", (name, age))
conn.commit()
def get_user_by_id(self, user_id):
with self.connect() as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
return cursor.fetchone()
์ฌ์ฉ ์์
# DAO ๊ฐ์ฒด ์์ฑ ๋ฐ ์ฌ์ฉ
user_dao = UserDAO('test.db')
user_dao.create_table()
user_dao.insert_user('Alice', 25)
user = user_dao.get_user_by_id(1)
print(user) # ์ถ๋ ฅ ์์: (1, 'Alice', 25)
2. DTO (Data Transfer Object)
DTO๋?
DTO๋ ๋ฐ์ดํฐ๋ฅผ ๋คํธ์ํฌ๋ฅผ ํตํด ์ ์กํ๊ฑฐ๋ ๊ณ์ธต ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๊ฐ์ฒด์ ๋๋ค. ์ฃผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์ ์กํ๋ ์ญํ ์ ํ๋ฉฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํน์ ์ปฌ๋ผ ๊ฐ๋ค์ ์ ์ฅํ๋ ์ฉ๋๋ก ์ฐ์ ๋๋ค. ๋ฐ์ดํฐ์ ์ ์ฅ, ๋ณํ์ ์ํํ ๋ฟ ๋น์ฆ๋์ค ๋ก์ง์ ํฌํจํ์ง ์์ต๋๋ค.
DTO์ ์ญํ
- ๋ฐ์ดํฐ ์ ๋ฌ: ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ ๋ค๋ฅธ ๊ณ์ธต์ ๋ฐ์ดํฐ๋ฅผ ๋ชจ์ ์ ์กํฉ๋๋ค.
- ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ์ ์ง: ๋ฐ์ดํฐ๋ฅผ ๋จ์ํ ์ ๋ฌํ๋ ์ญํ ์ ํ๋ฏ๋ก ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ ๋ก์ง์ด ์์ต๋๋ค.
- ๋น์ฆ๋์ค ๋ก์ง ํฌํจํ์ง ์์: DTO๋ ๋จ์ํ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ฒด๋ก์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ์ง๋ง, ๋น์ฆ๋์ค ๋ก์ง์ ํฌํจํ์ง ์์ต๋๋ค.
Python์์ DTO ๊ตฌํ ์์
Python์์ DTO๋ ์ฃผ๋ก dataclass
๋ฅผ ์ฌ์ฉํด ๊ฐ๋จํ๊ฒ ์ ์ํ ์ ์์ต๋๋ค. ์๋ ์์ ๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ด๋ UserDTO
ํด๋์ค์
๋๋ค.
from dataclasses import dataclass
@dataclass
class UserDTO:
id: int
name: str
age: int
์ฌ์ฉ ์์
# DTO ๊ฐ์ฒด ์์ฑ
user_dto = UserDTO(id=1, name='Alice', age=25)
print(user_dto) # ์ถ๋ ฅ ์์: UserDTO(id=1, name='Alice', age=25)
3. VO (Value Object)
VO๋?
VO๋ ๋ฐ์ดํฐ๋ฅผ ์บก์ํํ์ฌ ๋ถ๋ณ์ ๊ฐ์ฒด๋ก ๋ค๋ฃจ๋ ๊ฐ ๊ฐ์ฒด์ ๋๋ค. ์ฃผ๋ก ํน์ ์ํ๋ฅผ ๋ํ๋ด๋ ์์ฑ๋ค์ ์งํฉ์ด๋ฉฐ, ๋์ผํ ๊ฐ์ ๊ฐ์ง๋ฉด ๋์ผํ ๊ฐ์ฒด๋ก ๊ฐ์ฃผํฉ๋๋ค. ๊ฐ์ด ๋ฐ๋์ง ์๋ ๋ถ๋ณ ๊ฐ์ฒด๋ก ๊ตฌํํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
VO์ ์ญํ
- ๊ฐ ์์ฒด๋ก ๋๋ฑ์ฑ ์ ์: VO๋ ์์ฑ ๊ฐ์ด ๋์ผํ๋ฉด ๋์ผํ ๊ฐ์ฒด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
- ๋ถ๋ณ ๊ฐ์ฒด๋ก ๊ด๋ฆฌ: VO๋ ์ํ๊ฐ ๋ณ๊ฒฝ๋์ง ์๋๋ก ์ค๊ณํ์ฌ ์ฝ๋์ ์์ ์ฑ์ ๋์ ๋๋ค.
- ๋น์ฆ๋์ค ๋๋ฉ์ธ ํํ: VO๋ ํน์ ๋น์ฆ๋์ค ๋ก์ง์์ ํ์ํ ์ํ๋ ๊ฐ๋ค์ ์ ์ํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
Python์์ VO ๊ตฌํ ์์
VO๋ ๋ฐ์ดํฐ์ ๊ฐ ๋ณ๊ฒฝ์ ๋ง๊ธฐ ์ํด @dataclass(frozen=True)
๋ฅผ ์ฌ์ฉํด ๋ถ๋ณ ๊ฐ์ฒด๋ก ์ ์ํ ์ ์์ต๋๋ค. ์๋ ์์ ๋ AddressVO
ํด๋์ค์
๋๋ค.
from dataclasses import dataclass
@dataclass(frozen=True)
class AddressVO:
street: str
city: str
zipcode: str
์ฌ์ฉ ์์
# VO ๊ฐ์ฒด ์์ฑ
address1 = AddressVO(street="123 Main St", city="Springfield", zipcode="12345")
address2 = AddressVO(street="123 Main St", city="Springfield", zipcode="12345")
print(address1 == address2) # ์ถ๋ ฅ: True (๊ฐ์ด ๋์ผํ๋ฏ๋ก ๊ฐ์ ๊ฐ์ฒด๋ก ๊ฐ์ฃผ)
DAO, DTO, VO์ ์ฐจ์ด์ ์ ๋ฆฌ
๊ตฌ๋ถ | DAO (Data Access Object) | DTO (Data Transfer Object) | VO (Value Object) |
---|---|---|---|
๋ชฉ์ | ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ์์ฉ ๊ด๋ฆฌ | ๋ฐ์ดํฐ ์ ์ก์ ์ํ ๊ฐ์ฒด | ๋ถ๋ณ์ ๊ฐ ๊ฐ์ฒด |
์ญํ | CRUD ์์ ์ํ | ๋ฐ์ดํฐ ๊ณ์ธต ๊ฐ ์ ๋ฌ | ๊ฐ ์์ฒด๋ก ๋๋ฑ์ฑ์ ๊ฐ์ง๋ ๊ฐ์ฒด |
์์ | UserDAO , ProductDAO |
UserDTO , ProductDTO |
AddressVO , MoneyVO |
ํน์ง | ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋ถ๋ฆฌํ์ฌ ๋ฐ์ดํฐ ๊ด๋ฆฌ | ๋จ์ํ ๋ฐ์ดํฐ ์ ๋ฌ์ฉ | ๊ฐ์ด ๋์ผํ๋ฉด ๋์ผํ ๊ฐ์ฒด๋ก ๊ฐ์ฃผ |
๊ฒฐ๋ก
Python์์ DAO, DTO, VO๋ ๊ฐ๊ฐ ๋ฐ์ดํฐ ์ ๊ทผ, ์ ์ก, ๊ฐ ๊ฐ์ฒด ๊ด๋ฆฌ๋ฅผ ์ํด ์ฌ์ฉ๋๋ ๋์์ธ ํจํด์ ๋๋ค. ์ด๋ค ๊ฐ์ฒด๋ฅผ ํ์ฉํ๋ฉด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ, ์ ์ง๋ณด์์ฑ, ์์ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
- DAO๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ์์ฉ์ ๋ด๋นํ๋ฉฐ, CRUD ์์ ์ ๋ถ๋ฆฌํด ์ฝ๋๋ฅผ ๋ชจ๋ํํฉ๋๋ค.
- DTO๋ ๋ฐ์ดํฐ ์ ๋ฌ์ ์ํ ๊ฐ์ฒด๋ก์, ์ฃผ๋ก ๊ณ์ธต ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
- VO๋ ๊ฐ ์์ฒด๋ฅผ ์๋ฏธํ๋ ๋ถ๋ณ ๊ฐ์ฒด๋ก, ๊ฐ์ ๊ธฐ๋ฐํ ๋๋ฑ์ฑ์ ๊ฐ์ง๋ฉฐ ์ฝ๋์ ์์ ์ฑ์ ๋์ ๋๋ค.
์ด์ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ํตํด Python ํ๋ก์ ํธ์์ ๋ฐ์ดํฐ ๊ด๋ฆฌ์ ์ ์ก์ ๋์ฑ ํจ์จ์ ์ผ๋ก ํ ์ ์์ต๋๋ค.