Skip to content

[2단계 - 점심 뭐 먹지] 앵버(최승수) 미션 제출합니다.#262

Merged
igy95 merged 120 commits intowoowacourse:aydenotefrom
aydenote:step-2
Mar 28, 2025
Merged

[2단계 - 점심 뭐 먹지] 앵버(최승수) 미션 제출합니다.#262
igy95 merged 120 commits intowoowacourse:aydenotefrom
aydenote:step-2

Conversation

@aydenote
Copy link
Copy Markdown

@aydenote aydenote commented Mar 17, 2025

안녕하세요, 카일
이번 리뷰도 잘 부탁드립니다!

리팩토링할 부분이 많았지만, 시간이 부족하여 우선 동작만 가능하도록 구현했습니다. 죄송합니다.🙇‍♂️
피드백 주시면 내용을 포함하여 리팩토링 진행하겠습니다!!

학습 목표

이번 미션을 통해 다음과 같은 학습 경험들을 쌓는 것을 목표로 합니다.

  • UI와 도메인 영역을 분리할 수 있는 설계를 고민해보고, 목적에 맞게 객체와 함수를 활용
  • TDD 방식으로 개발하며, 단위 테스트 기반으로 점진적인 리팩터링

제출 전 체크 리스트

  • 기능 요구 사항을 모두 구현했고, 정상적으로 동작하는지 확인했나요?
  • 기본적인 프로그래밍 요구 사항을 준수하고 있는지 확인했나요?
  • 테스트 코드는 모두 정상적으로 실행되나요?
  • (해당하는 경우) 배포한 데모 페이지에 정상적으로 접근할 수 있나요?

리뷰 요청 & 논의하고 싶은 내용

1) 이번 단계에서 가장 많이 고민했던 문제와 해결 과정에서 배운 점

  1. 모달, 리스트, 이벤트 핸들러 등 서로 다른 역할을 하는 부분들을 한 곳에 모아두면 코드가 복잡해진다는 것을 경험했습니다. 이를 개선하기 위해 관심사별로 컴포넌트를 분리하고 각 모듈이 독립적으로 동작하도록 구조를 개선했습니다. 특히, 이벤트 등록과 컴포넌트 결합의 책임은 컨트롤러에서 관리하고, 컴포넌트는 UI 표현에만 집중하도록 구현하려고 노력했습니다.

2) 이번 리뷰를 통해 논의하고 싶은 부분

  1. step-1에서 step-2로 기능을 확장하는 과정에서 사이드 이펙트가 많이 발생했습니다. 이로 인해 컴포넌트에 전달되는 인자가 늘어나고 내부 로직이 복잡해져 오히려 재사용하기 어려운 컴포넌트가 되어버렸습니다. 이러한 사이드 이펙트를 줄이고 재사용성을 높이기 위해서는 어떤 방식으로 개선해 나가야 할까요?

  2. 업데이트가 발생할 때마다 ListController를 다시 호출하여 컨테이너의 innerHTML을 초기화하고 새로운 리스트 요소를 생성하여 DOM에 다시 추가하는 방식으로 재렌더링 효과를 구현했는데, 해당 방법은 변경된 매장 정보만 리렌더링 되는 것이 아니라 전체 매장 정보가 다시 렌더링되어 과하고 생각합니다. 현재 코드에서 어떤 방향으로 개선해야 업데이트된 매장만 리렌더링 시킬 수 있을까요?


✅ 리뷰어 체크 포인트

1단계

  • UI를 컴포넌트 단위로 분리했는가?
  • 재사용 가능한 컴포넌트를 고려했는가?
  • 주요 기능 시나리오에 대한 E2E 테스트를 작성했는가?

2단계

  • 오류 상황(예: 잘못된 입력)에 대해서도 테스트 케이스를 정의했는가?
  • 타입 정의를 적절히 사용하여 컴파일 오류 없이 안정적으로 동작하는가?
  • 로컬/배포 환경에서 테스트가 정상적으로 동작하는지 확인했는가?

hoyyChoi added 30 commits March 5, 2025 17:57
@igy95
Copy link
Copy Markdown

igy95 commented Mar 17, 2025

UX 피드백

  • 즐겨찾기에 있는 아이템에서 버튼을 토글하면 바로 사라지지 않는데 의도이신지 궁금합니다!

@igy95
Copy link
Copy Markdown

igy95 commented Mar 17, 2025

이번 리뷰를 통해 논의하고 싶은 부분

  1. 구체적으로 어느 컴포넌트에서 어떤 사이드 이펙트가 있었나요? 그리고 왜 그렇게 구현할 수밖에 없었는지 부연설명 해주시면 좋을 것 같습니다~!
  2. 데이터가 변경된 지점에만 DOM을 다시 그리는 방식을 적용하고 싶다면, 변경 전후의 요소를 비교하여 새로 그릴 부분만 추리는 과정이 필요하지 않을까요? React에서는 이를 해결하기 위해 가상의 DOM을 계산하는 diffing 알고리즘을 도입하였는데 이와 관련된 아티클을 찾아보셔도 좋을 것 같네요!

Copy link
Copy Markdown

@igy95 igy95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 앵버~ 리뷰 코멘트 및 논의 내용에 대한 답변 달아두었으니 확인 후 재요청 부탁드립니다 👍

Comment on lines +3 to +5
export function generateUniqueId() {
return crypto.randomUUID();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 유틸은 재사용성을 위해 다른 파일로 빠지는 게 좋을 것 같습니다 !

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유니크한 ID를 반환하는 함수가 store라는 파일명에 들어있는 게 적합하지 않은 것 같아서 다른 파일로 분리하였습니다~

Comment on lines +7 to +16
export function getRestaurantStorage() {
if (!localStorage.getItem("restaurant")) {
localStorage.setItem("restaurant", JSON.stringify(LIST_ITEM_CONTENTS));
}
return JSON.parse(localStorage.getItem("restaurant"));
}

export function setRestaurantStorage(restaurantInformation) {
localStorage.setItem("restaurant", JSON.stringify(restaurantInformation));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로컬 스토리지 계층과 도메인 계층을 분리해볼 수 있지 않을까요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

도메인과 로컬 스토리지를 별도의 모듈에 두고 도메인 계층은 이 저장소 모듈을 호출하도록 수정하였습니다!

Comment on lines +30 to +36
all: "전체",
ko: "한식",
ch: "중식",
ja: "일식",
we: "양식",
as: "아시안",
etc: "기타",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 네이밍은 되도록 지양하시면 좋겠습니다. 맥락을 알고봐도 각각의 줄임말이 무엇을 지칭하는지 한번에 파악하기 힘들기 때문이에요.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

줄임말 사용을 되도록 지양하겠습니다~ 감사합니다!

Comment on lines +2 to +9
const categoryNames = {
none: "선택해주세요.",
5: "5분 내",
10: "10분 내",
15: "15분 내",
20: "20분 내",
30: "30분 내",
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

distance라는 데이터와 *분 내라는 포맷된 문자열을 분리해보면 어떨까요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

distance 데이터에 "분 내" 라는 문자열 값이 포함되지 않도록 분리해보았습니다!

export function formatDistance(distanceMap) {
  const categoryNames = {
    none: "선택해주세요.",
    5: "5",
    10: "10",
    15: "15",
    20: "20",
    30: "30",
  };

  return distanceMap.map((distance) => `${categoryNames[distance]}분 내`);
}

Comment on lines +22 to +24
updateInformation(): void {
this.#information.favorites = !this.#information.favorites;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드의 이름이 동작에 비해 넓은 것으로 보입니다. updateInformation이라고 하면 information의 모든 필드를 업데이트 가능한 것으로 이해될 것 같아요!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updateInformation -> updateFavorite 으로 수정하였습니다. 감사합니다!

const restaurantList = new RestaurantList(storedRestaurants);
restaurantList.deleteRestaurant(restaurantElement.dataset.id);
},
cancle: () => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오타 있는 것 같네요~

Copy link
Copy Markdown
Author

@aydenote aydenote Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다, cancle-> cancel로 오타 수정하였습니다.😂

</p>
</div>
</div>
<img src="${renderFavoritesImg(favorites)}" alt=favorites class="favorites-icon" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • alt""이 필요해 보이네요
  • 웹 접근성 측면에서 보자면, alt의 설명이 좀 더 직관적이었으면 좋겠습니다. '즐겨찾기 버튼'이라던가, 실제 사용자의 입장에서 이해가 되게 작성해보면 어떨까요?

Copy link
Copy Markdown
Author

@aydenote aydenote Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alt 속성을 실제로 사용하게 될 사용자 입장에서 생각해보면 내용이 부족했던 것 같습니다.
혹시, alt 속성을 자세히 적어서 텍스트가 길어져도 상관 없을까요?

@aydenote
Copy link
Copy Markdown
Author

aydenote commented Mar 28, 2025

안녕하세요, 카일.

리뷰 반영이 늦어서 죄송합니다.🙇‍♂️

점심 뭐 먹지 - 배포 링크

개선

  1. 로컬 스토리지 계층과 도메인 계층을 분리해볼 수 있지 않을까요?
export function getRestaurantStorage() {
  if (!localStorage.getItem("restaurant")) {
    localStorage.setItem("restaurant", JSON.stringify(LIST_ITEM_CONTENTS));
  }
  return JSON.parse(localStorage.getItem("restaurant"));
}

export function setRestaurantStorage(restaurantInformation) {
  localStorage.setItem("restaurant", JSON.stringify(restaurantInformation));
}

=> RestaurantRepository라는 하나의 Restaurant 정보 저장 모듈을 만들어 기능을 관리하였습니다.

const STORAGE_KEY = "restaurant";

export const RestaurantRepository = {
  getAll: function () {
    const savedData = localStorage.getItem(STORAGE_KEY);
    if (savedData) {
      return JSON.parse(savedData);
    }
    return;
  },

  save: function (restaurantInformation) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(restaurantInformation));
  },
};

export default RestaurantRepository;

답변

UX 피드백 즐겨찾기에 있는 아이템에서 버튼을 토글하면 바로 사라지지 않는데 의도이신지 궁금합니다!
=> 의도한 부분 맞습니다. 제 생각에는 사라지는 것도 UX 적으로 괜찮지만 사라지지 않는 것도 사용자가 실수로 토글하거나 해제했다가 다시 즐겨찾기에 등록하고 싶을 수도 있기 때문에 사라지지 않게 했습니다!

질문

  1. 이미지 alt 속성은 기타 다른 유튜브나 강의에서 작성된 내용을 보면 간략하게 적는 경우가 대부분인 것 같은데, 혹시, alt 속성을 자세히 적어서 텍스트가 길어져도 상관 없을까요?

@igy95 igy95 merged commit 274dd27 into woowacourse:aydenote Mar 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants