Facts
- 미완성 상태긴 하지만 영화 리뷰 STEP1 PR을 올렸다.
- 로또 미션 STEP 3 리팩토링 진행
Feelings
- 어쨌든 PR 을 올렸다는 것 자체가 마음을 조금 편하게 해줌.
- 한 번 재미있다고 생각하면 또 너무 재밌어서 계속 하고 싶음
- 날씨가 좋아서 기분이 좋았다.
Findings
- 오늘 받은 피드백 중에는 '다른 서비스가 여러 플랫폼에 서비스를 제공하기 위해 어떤 노력을 할지 고민해보면 많은 공부가 될 것이다' 라는 내용이 있었다. 이미 성장한 큰 서비스가 어떻게 생겨먹었고 굴러가는지 관심을 가지고 인사이트를 얻는 것도 큰 공부가 되겠음...
- 지난 PR 에서는 일단 로또 게임이 웹 UI 에서 돌아가게 만드는 것에 초점을 맞춰서 메서드고 코드 정리고 하나도 하지 않았었는데, 어찌저찌 돌아가기는 하지만 이를 다시 이해하는데 약간의 시간이 걸렸다. 복잡하니까 더 쳐다보기 싫은 그런 현상이 있었음...
- Controller 로직을 두고 여기서 view 를 주입받는 방식으로 구현하려고 했는데, 그러면 이미 view 에 너무 많은 의존성을 가진 Controller 의 메서드들이 web UI 에 해당하는 view 에서 사용하기 까다롭게 되어있어서 이를 리팩토링 하고 있다.
부끄럽지만 아래가 나의 기존 코드
class LottoGameController {
#view;
#vendingMachine;
#winningCalculator;
// ...
async purchaseAndIssueLottos() {
// 🤔 이미 이 메소드 안에서 view 의 메소드를 호출하고 있어서, view 의 구현에 영향을 받는다.
const purchaseAmount = await this.#view.getPurchaseAmount();
this.#vendingMachine.purchase(purchaseAmount);
const purchasedLottoList = this.#vendingMachine.lottos;
// 👀 여기도
this.#view.printPurchasedLottos(purchasedLottoList);
return purchasedLottoList;
}
async setWinningNumbers() {
// 👀 여기도
const { selectedNums, extraNum } =
await this.#view.getLottoWinningNumbers();
return new LottoWinningNumbers({
selectedNums: selectedNums,
extraNum,
});
}
// ... and more ...
}
controller 의 로직이 이렇게 되어있다보니, 주입받는 view 로직도 controller 의 구현에 맞춰야 해서 아래와 같이 이상하고 복잡한 코드가 등장했다.
class LottoGameViewWeb extends LottoGameView {
// ...
// controller 에서 이미 view 의 이 메서드를 비동기도 다루고 있어서 불필요한 promise 가 사용되었다.
async getPurchaseAmount() {
return new Promise(async (resolve, reject) => {
const button = document.getElementById('purchase-button');
button.addEventListener('click', async () => {
const input = document.getElementById('purchase-amount-input');
const purchaseAmount = input.value;
resolve(purchaseAmount);
});
});
}
// 여기도... 메서드명도 이 지경이다 보니 도대체 뭘 하는 메서드인지 나도 모르겠음 😏
#createButtonClickPromise() {
return new Promise((resolve) => {
const button = document.querySelector('.open-result-modal-button');
button.addEventListener('click', () => {
// 일반 번호들 가져오기
const selectedNumsElements =
document.querySelectorAll('.selected-number');
const selectedNums = Array.from(selectedNumsElements).map((input) =>
Number(input.value)
);
// 보너스 번호 가져오기
const extraNumInput = document.querySelector('.bonus-number');
const extraNum = Number(extraNumInput.value);
// 입력된 번호 컨트롤러로 전달
resolve({ selectedNums, extraNum });
// 모달창 열기
const modal = document.querySelector('.modal');
modal.classList.add('open');
// 😅 그리고 이해가 잘 안되니까 이렇게 과도하게 친절한 주석도 추가된 것 같음...
});
});
}
// ... and more ...
}
- 그래서 방식을 바꿔 controller 는 외부에서 데이터를 인자로 받아 도메인 모델들에게 전달해 게임의 기능을 수행시키고 다시 그 값을 반환해 외부에서 핸들링 하도록 수정했음... 그렇게 하니 controller 의 역할도 조금 가벼워졌고 view는 어떻게 구현되든 controller 를 잘 활용해 콘솔 기반이든 웹 UI 기반이든 동작하도록 만들 수 있어서 유연성이 증가했다. 내 생각보다 함수, 메서드의 단위를 더 잘게 쪼개야 하는듯. 이렇게 리팩토링을 시작하기 전에는 view 와 강결합이 되어있다는 생각 자체를 못했었음.
- 처음엔 아예 갈아엎을까 생각도 했지만, 만약 이게 실무라면 그렇게 할 수는 없을테니까 최대한 있는 코드에서 변경을 최소화 하면서 바꾸려고 노력하고있다.
- 그래서 아래와 같은 방식으로 변경을 해보았음... 이거는 웹 UI 에서 로또 게임을 돌리는 로직인데, 더이상 유저의 입력을 비동기로 처리하기 위해 Prmoise, resolve 를 활용할 필요가 없어짐 (그래도 연습은 했다)
- 에러 핸들링의 경우 이벤트 리스너의 콜백 함수가 비동기이다 보니, 상위 메서드인 run 에서 try catch 로 핸들링이 어려웠고... 일단 콜백 함수 내에서 then 과 catch 로 핸들링 하도록 만들었는데 조금 더 추상화해서 정리할 수 있을 것 같다.
class App {
#view;
#controller;
constructor() {
this.#view = new LottoGameViewWeb();
this.#controller = new LottoGameController();
}
run() {
try {
this.step1();
this.step2();
} catch (error) {
alert(error.message);
}
}
/**
* 구매 버튼을 클릭해 유저가 입력한 금액만큼 로또를 발행한다.
*/
step1() {
const $purchaseButton = document.getElementById('purchase-button');
const $purchaseInput = document.getElementById('purchase-amount-input');
$purchaseButton.addEventListener('click', () => {
const purchaseAmount = $purchaseInput.value;
this.#controller
.purchaseAndIssueLottos(purchaseAmount)
.then((purchasedLottoList) =>
this.#view.printPurchasedLottos(purchasedLottoList)
)
.catch((error) => alert(error.message));
});
}
// ...
}
Feedback
- 과제 리뷰 기한은 끝났는데 그래도 어찌저찌 마무리 해보겠다고 노력한 점은 잘했음
- 마음에 안든다고 갈아 엎지 않고 점진적으로 개선하려고 하는 점은 스스로 칭찬해주고 싶음
- 역시 새벽에 하는 코딩이 잘 됨. 시간을 조정해서 새벽시간에 공부를 할 수 있게 조절하는 것도 좋을 것 같다. 건강엔 나쁠 것 같지만...
Future Action
- 리팩토링 마무리 후 다시 블로깅
'TIL' 카테고리의 다른 글
[TIL] 2023-0926 테스트 (0) | 2023.09.27 |
---|---|
[TIL] 2023-0925 점진적 과부하 (4) | 2023.09.26 |
[TIL] 2023-0922 (0) | 2023.09.24 |
[TIL] 2023-0921 (1) | 2023.09.21 |
[TIL] 2023-0126 : 새 프로젝트 / 딥다이브 스터디 / 과제 (3) | 2023.01.27 |