240226~240303 TIL
2024. 2. 26. 07:59ㆍ스파르타_부트캠프/TIL
24.02.26(월)
오늘 한일
코딩 테스트
- 이진 트리 반전 문제풀이 및 정리
파이썬 과제
- Chapter4 가위,바위,보 웹사이트 버전 개발을 1차적으로 완료하였다.
- HTML, css를 편집하여 뷰를 조금 보기 좋게 다듬어었다.
- 최근 날짜순으로 정렬, 승부에 따른 필터링, 화면에 최대 개수 조절 등을 위해 GameService 클래스를 다음과 같이 수정하였다.
def find_game_records(self, reverse=False, sort_option='id', max_count=20, filtered_result=None) -> list[
GameResult]:
key_func = lambda x: x.id
if sort_option == 'id':
key_func = lambda x: x.id
elif sort_option == 'user':
key_func = lambda x: x.user
elif sort_option == 'computer':
key_func = lambda x: x.computer
elif sort_option == 'result':
key_func = lambda x: x.result
elif sort_option == 'game_datetime':
key_func = lambda x: x.game_datetime
records = self.repo.find_all()
if filtered_result and len(filtered_result) > 0:
records = [r for r in records if r.result in filtered_result]
records.sort(key=key_func, reverse=reverse)
return records[0:max_count] if max_count >= 0 else records
repository에서 데이터를 가져온 후 sort_option 정렬 조건을 각 Column을 기준으로한 람다로 설정하였으며, reverse 옵션에 따라 차순을 선택한다. max_count는 반환하는 레코드의 총 개수이며, filtered_result는 승,무,패에 따라 필터링한다.
- Service에서 데이터를 가져올 때는 Repository의 의존성이 강하다. 위의 코드처럼 find_all()함수로 모조리 가져온 후 필터링하면 안되고 Repository가 제공하는 함수를 최대한 사용해야한다.
- 문제는 필요한 비즈니스 로직의 요구사항에 맞게 Repository의 인터페이스를 최대한 많이 가져가야하는데 이를 예측하기 쉽지 않다. Repository에 위의 파라미터 옵션을 '똑같이' 추가해야할까? 이 부분에 대해 고민해봐야겠다.
도메인과 SQLAlchemy 분리에 대한 고민
도메인과 SQLAlchemy의 분리를 위해 다음과 같이 설계를 하였다.
# Domain
@dataclass
class GameResult:
user: int
computer: int
result: int
game_datetime: datetime
id: int = 0
# Alchemy
class GameResultAlchemy(g_db.Model):
id = g_db.Column(g_db.Integer, primary_key=True, autoincrement=True)
user = g_db.Column(g_db.Integer, nullable=False)
computer = g_db.Column(g_db.Integer, nullable=False)
result = g_db.Column(g_db.Integer, nullable=False)
game_datetime = g_db.Column(g_db.DateTime, nullable=True)
def convert_to_sqlalchemy(data: GameResult):
# data.user
return GameResultAlchemy(
user=data.user,
computer=data.computer,
result=data.result,
game_datetime=data.game_datetime
)
def convert_to_data(a: GameResultAlchemy):
return GameResult(
id=a.id,
user=a.user,
computer=a.computer,
result=a.result,
game_datetime=a.game_datetime
)
DB 테이블이 변경되면 GameResult, GameResultAlchemy, convert 함수 총 3개를 수정해야하며, 또 관련 테스트 함수 역시 수정한다. 너무 변경해야할 것이 많은 것 같은데 옳은 설계인지 모르겠다. Repository, Domain, Service 패턴에 대해 좀 더 면밀히 분석해서 Best Practice가 무엇인지 분석하도록 한다.
스프링
- 스프링 입문 강의를 완강하였다. Spring 상에서의 GET, POST 방식을 어떻게 Mapping하여 사용하는지 파악하였으며, JDBC, JdbcTemplate, JPA를 각각 Repository를 상속받은 객체를 구현하면서 사용법을 익혔다.
- 전체적으로 스프링을 어떻게 사용하는지 익혔고, 내일 클론 코딩에서 로그인, 회원가입 기능을 구현하면서 프레임워크 사용에 익숙해질 수 있도록 한다.
내일 할일
- 코딩 테스트 문제 풀이
- Chapter4 기능 구현 마무리 - 디자인 개선 / 전적 필터링 기능 고도화
- 인프런 JPA 강의 청취
- Spring 회원가입, 로그인 기능 구현
24.02.26(월)
오늘 한일
코딩 테스트
- 가장 긴 동일 값의 경로 문제풀이 및 정리
파이썬 과제
- Chapter3 과제를 마무리하였다.
- Chapter4 가위,바위,보 웹사이트 버전을 개발을 진행하였다.
- 스프링처럼 Repository, Service, Domain을 사용하여 프로젝트 설계를 진행하였다.
- 가장 난감했던 부분은 다음 코드였다. GameResultAlchemy는 g_db.Model을 상속 받는데 이 부분은 C++, Java에서는 본적이 없는 코드이다. 동적 상속을 위해서는 항상 g_db.Model을 사용하는데 이를 위해서는 g_db = SQLAlchemy()로 객체를 생성해야한다. 이 부분이 상당히 생소하여 클래스를 작성하는데 애를 먹었다.
g_db = SQLAlchemy()
class GameResultAlchemy(g_db.Model):
id = g_db.Column(g_db.Integer, primary_key=True, autoincrement=True)
user = g_db.Column(g_db.Integer, nullable=False)
computer = g_db.Column(g_db.Integer, nullable=False)
result = g_db.Column(g_db.Integer, nullable=False)
game_datetime = g_db.Column(g_db.DateTime, nullable=True)
- 동적 상속에 대해 간단히 정리하고 어떤 식으로 응용되는지 조사가 필요하여 정리를 진행할 예정이다.
내일 할일
- 코딩 테스트 문제 풀이
- Chapter4 마무리
- 인프런 강의 청취
'스파르타_부트캠프 > TIL' 카테고리의 다른 글
240229 TIL (0) | 2024.02.29 |
---|---|
240228 TIL (0) | 2024.02.28 |
240219-240225 TIL (0) | 2024.02.18 |
240213-240218 TIL (2) | 2024.02.13 |
비슷한 직무 JD 분석 (0) | 2024.01.22 |