-
Notifications
You must be signed in to change notification settings - Fork 38
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
[2단계 - 자판기] 호프(김문희) 미션 제출합니다. #61
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
호프 어려운 자판기 2단계 미션 진행하느라 너무너무 고생 많이했어요~ 😆
피드백 드릴 부분은 코멘트에 남겼는데요 아래 2가지 내용은 자주 코멘트로 언급한것 같아서 한번 더 정리했어요~
특히 네이밍은 저도 어려운 부분이고 늘 고민이 많이 드는데요 ㅎㅎ 지금부터 고민해보고 같은 기능을 다른 사람들은 어떻게 보게 될까를 생각해보면 조금씩 더 잘하게 될 수 있는것 같아요. 참고로 미래의 나도 다른 사람이라고 생각하면 더 의미있는것 같아요 😉
네이밍
메서드 네이밍을 보고 어떤 동작 또는 반환값이 있을지 상상해보면서 봤을 때 추측하기 어려운 부분들이 있었던것 같아요. 먼저 동작 가능한 코드를 작성하면서 충분히 고민할 시간이 부족했던 부분도 있을텐데요. 리팩터링 하면서 한번더 네이밍을 보고 어떤 동작 또는 반환값을 주는지 드러낼 수 있게 만들어 보면 어떨까요~?
메세지 상수화
confirm
, snackbar
의 경우 상수화한 메시지를 활용하는데, alert
같은 경우에는 그렇지 않은 경우들이 있는것 같아요. 통일해보면 어떨까요~?
src/css/index.css
Outdated
|
||
.snackbar.error{ | ||
background-color: var( --snackbar-error-bg-color); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EOL이 등장했어요!
src/css/loginPage.css
Outdated
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앗 이 공백은...!?
src/js/api/index.ts
Outdated
signUp: async (option) => { | ||
try { | ||
const response = await request("/register", { | ||
method: "POST", | ||
headers: baseHeader, | ||
body: JSON.stringify(option), | ||
}); | ||
return { ...response, isError: false }; | ||
} catch (error) { | ||
return { isError: true }; | ||
} | ||
}, | ||
|
||
login: async (option) => { | ||
try { | ||
const response = await request("/login", { | ||
method: "POST", | ||
headers: baseHeader, | ||
body: JSON.stringify(option), | ||
}); | ||
return { ...response, isError: false }; | ||
} catch (error) { | ||
return { isError: true }; | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구조가 비슷한 메서드를 한단계 추상화해서 만들어보면 어떨까요~? 재사용가능한 부분들이 보이는것 같아요 🤩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금보니 반복되는 부분이 많아서 준 리뷰 대로 조금 수정을 해봤습니다. 특히나 try-catch 에서 response 값을 객체 형태로 넘겨주는 부분은 모두 다 동일하기 때문에, 아예 request 함수에서 처리해주도록 했습니다.
물론 '회원가입' '로그인' '유저정보 수정' 등..의 여러 api 요청 메서드들을 한단계 추상화해서, 외부에서 매개변수만 변경하여 재사용 할만한 메서드 하나를 만들 수 있을 것 같긴하지만 그럴 경우 도메인로직에서 해당 메서드를 사용할 때, 헤더 정보나 url 정보를 불필요하게 알아야한다고 생각해서 말씀해주신 추상화는 하지 않았어요! 이 부분에 대해서 어떻게 생각하시나요~~?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
한단계 추상화했을 뿐만 아니라, 객체의 책임과 관련된 부분까지 고민해서 작업한 점이 너무 인상적이에요 👍🏻
그런데 const data = await response.json();
이 부분에서 response.json()
이 실패한 경우에 에러 처리는 어떻게 해줘야할지도 고민되는 것 같아요. fetch API 사용하는 로직은 앞으로도 계속 사용하는 부분이니 이 미션이 아니어도, 다음 미션에서 반영해보면 좋을 것 같아요!
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사소하지만 이런 공백라인도 동일하게 맞춰가면 좋을 것 같아요 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오..사소한 부분까지 알려주셔서 감사합니다 😄
61fa29c
this.router = { | ||
[HASH.PRODUCT_MANAGEMENT]: () => { | ||
this.productModerator.init(); | ||
}, | ||
[HASH.CHARGE_CHANGES]: () => { | ||
this.changesModerator.init(); | ||
}, | ||
[HASH.PRODUCT_PURCHASE]: () => { | ||
this.purchaseModerator.init(); | ||
}, | ||
[HASH.SIGNUP]: () => { | ||
this.signUpModerator.init(); | ||
}, | ||
[HASH.LOGIN]: () => { | ||
this.loginModerator.init(); | ||
}, | ||
[HASH.USER_INFO]: () => { | ||
this.userInfoModerator.init(); | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
준에게 배운것.... 👍 👍
src/js/moderator/productModerator.ts
Outdated
try { | ||
const product = this.productProcessMachine.update(id, name, price, count); | ||
const product = this.vendingMachine.updateProduct(id, name, price, count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addProduct
의 경우 객체로 인자를 넣고, updateProduct
는 4개의 인자를 순서대로 넣는데 혹시 일관되게 구현하지 않는 이유가 있을까요~?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
급하게 하느라 통일성을 지키지 못했네요 😭 😭 이 부분 수정해서 둘다 객체로 인자를 받도록 했습니다. 이렇게 사소한 부분까지 짚어주셔서 감사해요!
9716133
src/js/ui/productPageView.ts
Outdated
$("#products-list", this.$productStatusContainer).insertAdjacentHTML( | ||
"beforeend", | ||
productTemplate.product(product.get()) | ||
); | ||
} | ||
|
||
renderDeleteProduct(id: string): void { | ||
renderDeleteProduct(id: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
삭제된 프로덕트를 render한다가 조금 어색한것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단순히, 뷰에 보여주는 부분을 변경한다고해서 render-*
접두사를 써야한다고 생각해서 저런 요상한 네이밍이 나왔네요 ㅋㅋㅋㅠㅠ
근데 생각해보니 해당 함수가 렌더링된 아이템을 삭제해주는 작업을 해주기 때문에 deleteRenderedProduct
라고 수정해주었습니다 :D
감사합니다.
src/js/ui/snackbarUI.ts
Outdated
} | ||
|
||
open(type, message) { | ||
if (this.$container.childElementCount >= 3) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3은 어떤 의미를 가지는걸까요~? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
스낵바가 여러개가 동시에 화면에 보여져야할 경우 최대 3개까지 보여지게 해놨기때문에 들어간 숫자인데 이렇게 놓으면....정말 코드를 읽는 입장에서는 뭐지??! 싶겠네요 ... 상수로 분리해주겠습니다 :D 감사합니다.
@@ -0,0 +1,110 @@ | |||
const URL = "http://localhost:9000"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cypress-json을 활용해봐도 좋을것 같아요~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니다~ 훨씬 간결해졌네요 👍 👍 👍
cy.get("#email").type("test@test.com"); | ||
cy.get("#password").type("Abcd1234!"); | ||
cy.get(".submit-button").click(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
중복되는 부분을 재사용할 수 있게 리팩터링 한다면 테스트 코드의 가독성도 더 좋아질것 같아요~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분 cypress commands 사용해서 해결했습니다 :)
계속 반복해서 사용되는 signUp 과 login 을 커맨드로 빼놓으니까 너무 간결하네요
감사합니당 👍
b99dd1f
- 중복되는 부분 제거 (try-catch)
안녕하세요 준 😄 정말 좋은 리뷰 감사드립니다! 그럼에도 불구하고 아직 네이밍관련해서는 '더 좋은 네이밍' 에 대한 의문이 끊이질 않네요 😭 .. 준이 주신 피드백들 참고해서 앞으로 더 좋고 명확한 네이밍을 하도록 노력해보도록 하겠습니다 :D 혹시나 더 수정할 부분이 있거나, 궁금하신 점이 있다면 알려주시면 감사하겠습니다 🙇 🙇 |
호프~ 정말 빠르게 피드백 반영해주고, 고민한 과정까지 상세하게 남겨줘서 소통하는 과정이 너무 큰 즐거움이었어요! 우테코 수료할 때 쯤엔 "네이밍은 여전히 어렵지만, 이렇게 접근하면 더 나은 네이밍을 만들 수 있는것 같아!"라는 호프만의 철학이 있으면 너무 눈부실것 같습니다 🤩 너무너무 고생했구요 레벨2에서 만날게요! 😆 |
안녕하세요 헤인티! 오랜만에 뵙습니다 !
헤인티가 주신 피드백 반영하면서 정말 많이 학습할 수 있었어서 좋았어요!
로컬에서 실행하는 법
먼저 저번에 주신 enum, as const, readonly 에 대해 학습해봤는데요, 아래와 같이 정리 할 수 있었습니다. 아래 정리하면서 타입스크립트에 대해서 많이 학습 할 수 있었어요! 감사드립니다.
enum 을 사용하면 안되는 이유
결과적으로 말하면 enum을 사용하면 자바스크립트에서 Tree Shaking 이 되지 않습니다.
enum 은 JavaScript에 존재하지 않고, TypeScript 가 구현한 코드이기 때문에, 즉시실행 함수를 통해 구현됩니다.
그런데 번들러는 즉시실행함수를 ‘사용하지 않는 함수’라고 판단 할 수 없기 때문에 Tree-Shaking 이 적용되지 않습니다.
readonly 타입이란?
as const 란?
const foo = 'bar' as const
라고 선언 할 경우, 변수foo
의 타입은string
으로 확장되지 않고,bar
가 됩니다.좋은 코드리뷰 너무 감사드리구, 부족한 코드를...리뷰요청드리게 된 점 정말 죄송합니다. 😭