Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object Modeling #55

Open
Bartleby2718 opened this issue Oct 15, 2018 · 1 comment
Open

Object Modeling #55

Bartleby2718 opened this issue Oct 15, 2018 · 1 comment
Labels
question Further information is requested

Comments

@Bartleby2718
Copy link
Owner

Bartleby2718 commented Oct 15, 2018

@gongdo:
game state를 OutputHandler에게 줄 때 쓸 형식을 JSON으로 하기로 결정하고 serialize하다가 제가 봐도 좀 이상해 보이는 부분이 있어서 확실히 하고 싶어서 질문 드립니다.

  1. circular reference가 있으면 안될 것 같은데, 객체 모델링 시 서로 관련이 있는(?) 두 객체를 어떤 방식을 엮어야 하나요? RDBMS 모델링할 때는 FK(+many-to-many table)를 이용하고, graph DB에서는 edge를 이용하는데, DB 모델링만 실컷 해 보고 객체 모델링은 별로 안해봤다 보니 기본적인 것 같은데 모르겠네요. 그리고 관련이 있으면 항상 하나에서 다른 걸 갈 수 있어야 하는지, 연결 관계가 단방향이어도 되는지도 궁금해요. 지금 코드에서는 Deck에 있는 Card를 찾을 일은 있지만 Card에서 자신이 속한 Deck을 찾을 일은 없거든요.

  2. DB 모델링할 때 정규화 과정을 거치는 것처럼, 왠지 객체 모델링 할 때도 중복되는 데이터는 (적어도 field/attribute 중에는) 없어야 할 것 같은데 맞나요? 예를 들어 game.player_redgame.player_black이 있다고 했을 때 game.players, game.num_human_players, game.red_name처럼 shortcut 역할을 하는 것들은 method로 바꾸는 게 맞죠?

@Bartleby2718 Bartleby2718 added the question Further information is requested label Oct 15, 2018
@gongdo
Copy link

gongdo commented Oct 16, 2018

기본적으로 오브젝트 설계시 '행동'을 노출하여 상호작용하는게 가장 좋고, '값'을 수정하여 기능을 구현하는건 가능한 피해야 해요.
예를 들어 game이 decks[0]의 delegate를 설정해야 한다면,
game.decks[0].delegate = game.deck[0].cards[x] 라고 할게 아니라,
game.decks[0].selectDelegate()처럼 행동을 지정하고 이 행동이 내부의 상태(값)을 변경하도록 하는거죠.
이 때 이 행동은 파라미터가 필요할 수 있겠죠. 가령 각 deck에서 delegate를 선택하는 '규칙'을 파라미터로 전달하여 deck이 스스로 선택하게 할 수 있겠죠. (물론 이 게임에서는 각 deck이 독립적인 규칙을 가질필요는 없으므로 실제 구현은 전혀 다른 얘기가 되겠지만요.)

이런 방식으로 구현하면 오브젝트 A가 '소유'하는 오브젝트 B가 A에 대해 알 필요가 전혀 없으면서 자기 자신이 어떤 행동을 하고 그 결과로 자신의 상태가 어떻게 바뀌는지만 생각하면 되죠.
A와 B에 포함되는 필드를 어떻게 정할지는 그저 케바케라고 할 수 밖에 없고요.

RDBMS에서 중복은 죄악처럼 취급되지만 실제 프로그램에서는 위와 같이 개체간의 경계와 행동이 중요하지 각 개체 사이에서 데이터의 중복이 발생하는 건 문제가 없을 수도 있고 심지어 필연적일 수도 있어요.

예를 든 game.player_red와 game.player_black은 이미 game.players에 포함된 정보지만 충분히 유의미한 편의성을 제공하죠. 단, 이렇게 하려면 game.player_red와 black은 외부에서 '읽기'만 가능하고 '수정'이 불가능해야 하고, game 내부에서도 이들이 바뀌는 규칙이 명확해야 하겠죠.
또한 players의 각 요소와 red, black은 각각 동일한 오브젝트에 대한 레퍼런스(혹은 포인터)여야 하겠고요.

언어적으로 python에서 '노출하지만 수정이 불가능한 필드'라는게 있는지는 모르겠네요.
아마 대부분의 언어가 그런 건 따로 없고 대체로 getter 메서드로 처리할거에요.

state machine을 디자인할 때 주의할 점은, state는 시스템의 현재 '상태'를 나타낼 뿐이고 이것은 RDBMS와 1:1로 매칭되는 것이 아니라는 거에요. 또한 프로그램에서 그보다 더 중요한건 오브젝트의 행동이고요. 상태는 행동의 결과일 뿐.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants