10주차 프로젝트

아 오랜만에 쓰는 WIL이다.. 자꾸 글을 작성해놓고 안썼는데, 꼭 일요일마다 회고록을 작성해야겠다. 이번 주차는 성능 최적화 관련 과제이다. 원래 저번주차에 성능 최적화 주차였는데, 성능 최적화를 한주 없애고, SSR, SSG 부분이 생겼다. 저번주차는 정말 극악 주차였다. ㅜㅜ (크흠 준일코치님..)

본론

최적화가 안된 웹 프론트 페이지를 최적화를 시키는게 목표다. 10주차는 정말 여러가지로 많이 쓰였던 주차였다. 이전에 배웠던 useAutoCallback을 다시 사용하기도 했고, React Develoer Tools를 사용하면서 어디부분에서 렌더링이 많이 발생한지 체크를 해서 최적화를 해야한다. 이전에 사실 뭣도 모르고, useCallback, memo, useMemo를 그냥 남발 했는데, 이제는 여기서 왜 써야하는지 대충 감이 잡힌 거 같다. 

 

결론

벌써 10주가 끝났다는게 너무 아쉽다. 뭔가 다음주부터는 과제를 안하니까 허전한 느낌이 들거 같다. 다음주부터는 뭐해야할까 고민이 생각이 든다. 일단 기존에 항해에서 공부했던 것들을 싹 다 다시 복습해야겠단 생각이 든다. 

 

멘토링

준일 코치님 / ㅜㅜ 마지막 준코 멘토링..

 

10시부터 11시까지 멘토링을 진행했다. 멘토링은 평소와 처럼 진행했고, 마지막이라는 아쉬움을 담은채 멘토링을 진행했다.

 

질문

요즘 회사에서 시간날 때 ‘개발자를 위한 글쓰기 가이드’라는 책을 보고있습니다. 저도 블로그를 좀 잘쓰고싶은데, 다른분들꺼 블로그도 조금씩 보고있습니다. 준일 코치님 블로그를 보면 진짜 잘쓴다라는 생각이 있는데, 따로 블로그 주제를 어떤식으로 선정하고, 글의 형식을 어떻게 쓰시는지 궁금합니다!

 

답변

제가 주로 선정하는 주제는 반복적으로 하는 말 입니다.

Vanilla Javascript로 웹 컴포넌트 만들기

  • 위의 글을 작성한 이유는… 바닐라 자바스크립트 기반의 스터디를 진행했었는데, 이 때 코드리뷰를 많이 했었고, 모든 리뷰에 반복적으로 등장하는 이야기를 모아서 글로 만들었어요.

내가 평소에 생각하고 자주 이야기하는걸로 글을 써야 술술 써지는 것 같아요.

나는 왜 이직을 하고 싶은가

나는 왜 개발자를 하고 싶은가

황준일은 왜 개발자를 했는가 → 초등학교 때 꿈을 적는 란에 “프로그래머” 라고 썼음. 막연하게 하고 싶었음!

유년시절 이야기 (1)

유년시절 이야기 (2)

유년시절 이야기 (3)

  1. 주제선정
  2. 목차를 뽑고
  3. 목차에 들어갈 내용을 간략하게 적어놓고
  4. 나중에 다 채워넣고
  5. 맞춤법 검사하고
  6. 올리기!
# SSG 만들기!

## CSR, SSR, SSG

## SSR vs SSG

## 그래서, 어떻게 만들어!?

### html template

### App Component

### Metata

### 결합

## 배포!

## 정리
  • 멘토링 마지막인데 정말 도움 되는 말씀해주셔서 감사했습니다.
  • 저도 감사드려요 민기님!!

나에게 있어 준일코치님을 보면서 많이 생각이 변했다는 생각이 든다. 예전에는 개발자는 단순히 개발하는사람이라는 생각이 들었는데, 문제 해결이 제일 중요하다라는 관점을 나에게 알려주신 코치님이다. 너무 감사하다. 나중에 언젠가 또 뵙게 되면 꼭 커피라도.. 사드려야겠단 생각이 든다.

 

테오 코치님 멘토링 / 눈물 나올뻔한 마지막 멘토링..

멘토링은 마지막이다보니 질문 답변에 대한 내용보다 회고 형식으로 진행이 되었다. 3가지 파트를 나눠서 진행했는데 다음과 같다.

 

첫번째 회고

10주간 좋았던 기억들..

일단 먼저 너무 좋았던 기억들이 너무 많았다. 여러가지가 있었는데, 퇴근하고 나면 힘들어서 누워있고 싶기 마련인데 항해하면서 자연스럽게 공부하는 습관이 길러진거같다. 자연스럽게 퇴근하고 새벽 1~2시까지 공부하게 되었다.

그리고 맨날 질문봇처럼 여러 팀 돌아다니면서 질문 많이했는데 답변을 항상 정성껏 해주셔서 다른팀분들에게 너무 감사했다. 

마지막으로 BF만들기하면서 너무 재밌었다. 사실 6시간만에 끝내려고 한 해커톤느낌이였는데, 현실은 기획만 6시간만 하게되었다. 햄버거 하나 사들고 회의실가서 열심히 토론 하고 밤 11시 넘어서까지 공부했던게 너무 재밌었다. 나에게 첫 개발 협업이라 그런가 너무 즐거웠던 기억이다.


두번째 회고

고마웠던 사람들.. 감사했던 분들에게 샤라웃하기

난 아무래도 2팀분들에게 샤라웃했던거같다. 먼저 채영님이 어려운거 있을 때 마다 항상 도와주셔서 제일 감사했고, 도은님, 윤우님 소연님, 진희님에게 너무 감사했다 궁금한거나 고민이 있을 때 제일 먼저 나서서 도와주셔서 너무 감사했다. 우리팀 최고!

 

세번째 회고

힘들게 했던 것들..

여러 힘들게 했던 것들이 있는데 역시나 나에게 있어서는 기존 경력을 다 버리고, 개발자로 가는게 좀 고민이 많았던 거같다. 사실 항해 하면서도 고민이 많았던 부분이다. 이렇게까지 개발자로 해야하나라는 생각이 들기도 했고, 다시 개발자로 간다면 신입부터 다시 시작해야하는데, 그 부분이 참 고민이 많이 생겼던 거같다. 

하지만 그래도 나는 개발자가 너무 재밌는 거같다. 나는 뭔가 계속 해서 발전 하는게 너무 좋다. 요즘 취업이 솔직히 너무 안좋은 시장에서 취업을 할 수 있을진 모르겠지만 그래도 하는데까지는 해야겠다. 

 

10주간 테오 코치님, 준일 코치님 너무 감사했습니다. 그리고 이 외에도 오프코치님 성호코치님 너무 감사했습니다. 10주간 개발자 선배로 진실적인 답변 도움 많이주시고 인성적으로도 너무 훌륭한 코치님 이셨다고 생각합니다. 감사합니다!!


수료식

수료식 날에는 전반적으로 편안한 분위기 속에서 진행되었다. 수료식 가기전에 텐동집가서 먹었는데 너무 맛있었다! 하지만 세트를 괜히 시켰나보다.. 너무 배불렀다.. 새우튀김이 진짜 맛있었다!

 

발표 및 시상식

이 후에 본격적으로 수료식이 시작되었다. 간단하게 대기를 하다가 이제 발표하신 분들이 있었는데, 의찬님을 시작으로 채은님, 지현님, 영서님, 태영님이 발표를 시작헀다. 개인적으로 태영님 발표가 제일 기억에 남았다. 원표 학메님한테 마지막에 감동적인 편지를 주셨는데 너무 기억이 남는거 같다. 

 

이후에 시상식에서 상장 받으신분들이 솔직히 잘 기억이 나질 않는다 ㅜㅜ 기억에 남는거는 도은님이 성실상으로 받은 기억밖에 없다. 그리고 배스트팀으로 4팀이 받으셨는데 너무 축하드린다. 다들 너무 열심히 하는게 보였고

BF 만들기 결과

그리고 수료식날 우리가 만든 BF 롤링페이퍼를 공개하기로 했다. 위에서 말했듯이, 사실 BF를 만들면서 내가 한 비중은 너무 많지 않았다. 하지만 그래도 여러모로 협업 경험을 배울 수 있어서 너무 좋았다. 같이 함께한 2팀분들이 너무 고생 많으셨다. 그리고 코치님, 다른 팀원분들에 대한 반응이 좋았다. 여러모로 뿌듯했다.

 


네트워킹 파티

발표 및 상장 수여식을 진행한 후 항해 6기 전체분들이랑 사진 및 팀별로 사진 촬영을 진행했다. 그리고 네트워킹 파티는 1차는 6시부터 ~ 9시까지 진행했다. 나는 아쉽게도 야간 당직 근무라 10시까지 회사를 가야하는 상황으로 1차만 하고 중간에 갔다. ㅋㅋ 분위기론 거의 전체다 밤샘각 이였는데 다 아침에 밤새고 갔던 거 같다. 1차만 하고 갔지만 너무 재밌었고 다음에도 이런 네트워킹 기회가 있었으면 좋겠다. 다들 10주간 고생 많으셨어요!

 

마지막..

2페어팀 분들 너무 감사했습니다. 
먼저 우리팀인 채영님, 소연님, 도은님, 윤우님, 아쉽게도 못오신 진희님..
그리고 6팀 지현님, 민재님, 수현님, 희진님, 태영님, 영민님

그리고 항해 다른 팀 여러분들 10주간 너무 감사했습니다. 다들 항상 좋은 결과 있으셨으면 좋겠습니다.

 

function solution(n) {
    const ternaryString = n.toString(3);
    const reverse = [...ternaryString].reverse().join('');
    
    const result = parseInt(reverse, 3); // '22111'을 3진수로 해석
    return result;
}

 

이 문제의 주요 내용은 3가지이다.

1. 10진법 -> 3진법 바꾸는 방법

2. 문자열 뒤집기 방법

3. 3진법 -> 10진법

1. 진법 바꾸는 방법

주요 예시:

// 10진수 → 2진수 (Binary)

const decimal = 27;
const binary = decimal.toString(2); // radix: 2

console.log(binary); // "11011"


// 10진수 → 8진수 (Octal)


const decimal = 27;
const octal = decimal.toString(8); // radix: 8

console.log(octal); // "33"


//10진수 → 16진수 (Hexadecimal)

const decimal = 27;
const hexadecimal = decimal.toString(16); // radix: 16

console.log(hexadecimal); // "1b"

 

2. 문자열 뒤집기 방법

[...str] → reverse() → join('')

const str = "Hello World";

// Spread 연산자로 문자열을 배열로 만든 후 reverse, join
const reversedStr = [...str].reverse().join('');

console.log(reversedStr); // 출력: "dlroW olleH"

 

3. 3진법 -> 10진법

JavaScript에서는 parseInt() 함수를 사용하여 특정 진법의 문자열을 10진법 숫자로 쉽게 바꿀 수 있음.

const myNumberString = '22111';
const decimalValue = parseInt(myNumberString, 3); // '22111'을 3진수로 해석

console.log(decimalValue); // 229

 

7주 차 프로젝트

7주차 과제는 TDD 관련된 내용이다. TDD 강의는 사놨지만, 사실 인프런에서 제로초님꺼 TDD 관련 강의를 결제 해놓고 다른 거를 하느라 TDD를 제대로 안해봤다. 하지만 이번 과제를 통해 TDD를 배운다는 생각에 너무 좋았고, 이번 기회에 마스터는 못하지만 어느정도 개념을 알자라는 목표로 다가갔다.

본론

일단 이번과제에는 테스트코드를 작성하기전에 난이도를 선택할 수 있다. 브런치별로 나뉘어져있는데, easy, medium, hard가 있다.
각각의 특징으로는 easy는 단위 테스트만 작성, medium은 통합테스트 + 단위 테스트, hard는 사실 잘모르겠다. 단위 + 통합 + 무언가 하나 있는데 하나 더 만들어야 hard 기본과제가 통과한다. 참고로 나는 어려워서 medium을 했다..

 

단위 테스트 
또한 이번 과제를 진행하기위해서는 기본적으로 만들어진 컴포넌트가 있는데, 만들어진 컴포넌트를 단위 테스트를 작성하는 것이 목표이다. 다음과 같이 단위테스트의 기본 틀이 있다. 

// hooks 파일

import { useEffect, useState } from 'react';

import { fetchHolidays } from '../apis/fetchHolidays';

export const useCalendarView = () => {
  const [view, setView] = useState<'week' | 'month'>('month');
  const [currentDate, setCurrentDate] = useState(new Date());
  const [holidays, setHolidays] = useState<{ [key: string]: string }>({});

  const navigate = (direction: 'prev' | 'next') => {
    setCurrentDate((prevDate) => {
      const newDate = new Date(prevDate);
      if (view === 'week') {
        newDate.setDate(newDate.getDate() + (direction === 'next' ? 7 : -7));
      } else if (view === 'month') {
        newDate.setDate(1); // 항상 1일로 설정
        newDate.setMonth(newDate.getMonth() + (direction === 'next' ? 1 : -1));
      }
      return newDate;
    });
  };

  useEffect(() => {
    setHolidays(fetchHolidays(currentDate));
  }, [currentDate]);

  return { view, setView, currentDate, setCurrentDate, holidays, navigate };
};
// 테스트 코드

it('view는 "month"이어야 한다', () => {});


미리 사전에 작성이 된 코드를 테스트 하는 것이 목표이다. 이렇게 구현체는 없고, 틀만 만들어진 단위 테스트는 한 100개정도 있는데, 다 작성을 해야한다. 그리고 이게 끝나면 또한 기본과제의 마지막 테스트인 통합 테스트가 남아있다.

 

통합 테스트 

describe('일정 CRUD 및 기본 기능', () => {
  it('입력한 새로운 일정 정보에 맞춰 모든 필드가 이벤트 리스트에 정확히 저장된다.', async () => {
  });

  it('기존 일정의 세부 정보를 수정하고 변경사항이 정확히 반영된다', async () => {});

  it('일정을 삭제하고 더 이상 조회되지 않는지 확인한다', async () => {});
});

 

단위 테스트처럼 틀이 있는데, 통합테스트도 마찬가지로 이 것을 구현하는 것이 목표다.

 

심화과제

마지막 심화과제로는 App.tsx에 비즈니스 로직 및 모든 컴포넌트들이 한 곳에 다있는데, 이 것을 리팩토링하고 테스트 5개를 구현하는 것이 목표이다. 리팩토링 까지는 진행을 했는데, 리팩토링을 하다보니 props가 너무많아 context api를 사용하여 리팩토링을 하다가 기본 과제의 테스트 코드가 꺠지면서 좀 애를 먹었다. 또한 단위테스트 파일을 만드는데 너무 오래걸려 결국 심화과제를 다 못끝냇다.. ㅜㅜ

 

결론

기본과제는 심화과제를 다 못해서 fail이 발생했다.. 다음주차도 tdd인데 다음주차에는 꼭 기본, 심화 모두 fail이 발생하지 않도록 해야겠다.
그리고 항상 고민이 있던게 코드를 어떻게 유지보수를 잘할 수 있을까에 대한 의문이 많았다. TDD를 배우다보니까 자연스럽게 테스트를 해야하므로, 코드를 잘게 분리하는 연습을 하는거 같다.

 

멘토링

이번 주차에는 성호코치님에게 멘토링을 했는데, 배운게 많은거 같다..

https://mo4811.tistory.com/119

 

[TIL] 20250819 회고

오늘 한 것easy 테스트 코드 진행, 모두 완료성호 코치님 멘토링모르는 것아직 테스트 코드에 종류가 많은 것 같다. 모르는 부분에 대해 키워드 위주로 정리를 하려했는데, 아직 사용을 안해봐서

mo4811.tistory.com

회고록에도 적어뒀지만, 

 

항커톤

2팀 멤버중 도은님, 진희님, 윤우님, 소연님, 나까지 합쳐서 5명에서 토요지식회에 발표할 내용을 위해 간단하게 프로젝트를 하나 만들기로했다. 사실 같이 하는 프로젝트가 처음이기에 설렜지만, 좀 구경만 한거같다. 다들 아무래도 개발자시고, 실무에 있으시다보니 기본셋팅과 컨벤션과 lint설정등을 다해주셨다. 하루안에 다 끝내려고 목표를 했는데, 기획만 하다보니 시간이 다 가버렸다. 생각보다 고려해야할 게 많았다. 

 

나는 쉬운 것을 맡아서.. 그래도 구현하는데는 오래걸리지 않을거같지만 다하고 나면 다른 분들을 좀 더 도와줘야겠단 생각이 든다.

깍두기 개념으로 참가한지라 약간의 의견만 제시했지만 매우 보람찼다.

발제 끝나고 프로젝트 계획 짜는 중..

혹시 같은 기수 분들이 블로그 보는 분들이 있을 거 같아서 프로젝트 내용은 생략하겠다 껄껄

오늘 한 것

  • easy 테스트 코드 진행, 모두 완료
  • 성호 코치님 멘토링

모르는 것

아직 테스트 코드에 종류가 많은 것 같다. 모르는 부분에 대해 키워드 위주로 정리를 하려했는데, 아직 사용을 안해봐서 내일 다시 전부 정리해봐야겠다.

멘토링

오늘 석호코치님에게 멘토링을 듣고 여러가지 많이 멘탈적으로 배운거같다.
성장관련하여 질문했는데, 배움에는 항상 지름길이 없고 항상 꾸준히 노력하는자가 좋은 결과가 있지 않나 생각이든다.

그리고 소연님 질문중에 번아웃 관련하여 공감이 되는게 나도 취업하고 이렇게 까지 공부해야하나 생각이 가끔식 들곤한다. 전직 이라는 문턱을 두고 이렇게 까지해야하나.. 생각이 들어서 여러가지 스트레스가 받았는데, 뭔가 취업이라는 주제를 가지고 코딩을 하면 안될거같다. 뭔가 재밌고 즐겁게 할 수 있는 더 위의 목표를 두고 개발을 해야겠단 생각이든다.

6주 차 프로젝트

이번 주차는 FSD에 관련된 내용이다. Feature Sliced Design 패턴의 관련된 내용이다. FSD를 각자 적절하게 활용하여 과제를 진행하는 게 이번 주차의 목표이다.

 

본론

FSD는 총 7단계로 구성이 되어있는데 그중 Processes 계층은 이제 사용을 안 하기에 6단계로 보통 구성되어 있다고 생각하면 된다.

  • app: 애플리케이션의 진입점으로, 초기화, 라우팅, 전역 스타일 및 스토어 설정 등을 담당
  • pages: 완전한 애플리케이션 페이지로, 위젯과 기능들로 구성
  • widgets: 독립적이고 큰 UI 블록 (예: 헤더, 사이드바, 게시물 댓글 목록).
  • features: 사용자 상호작용과 관련된 비즈니스 가치를 제공하는 로직 (예: 인증, 댓글 달기, 장바구니에 추가).
  • entities: 애플리케이션이 다루는 비즈니스 개체, 즉 '명사' (예: 사용자, 제품, 댓글).
  • shared: 비즈니스 로직과 무관한 재사용 가능한 코드 (예: UI 키트, API 클라이언트, 유틸리티 함수).

(테오 블로그 내용)

 

나는 위의 내용을 어떻게 잘 조합할까 생각을 했다. 밑의 사진은 내가 프로젝트를 하면서 컴포넌트를 나눈 기준이다.

 

1. 빨간색 피쳐

2. 파란색 엔티티

3. 초록색 위젯 

위의 사진을 가지고 준일 코치님에게 질문했던 부분은 다음과 같다.

질문 : 제가 궁금했던 것은 PostItem을 엔티티로 하게된다면, 단방향 흐름에 따라 엔티티 안에 피쳐가 못 온다는 부분을 알고 있어서 PostItem을 위젯으로 했는데요. 제가 생각한 부분이 틀릴까요? 아니면 PostItem 전체를 엔티티로 두고 EditIcon, TrashIcon, DetailIcon도 그냥 엔티티로 두어야 했을까요?

답변 : widget으로 두거나 혹은 feature로 둬도 무방하다고 생각해요 ㅎㅎ또 다른 방법은, PostItem이 아니라 TableItem이라는 UI로 하나 추상화 한 다음에 여기에 entities나 features로 만들어진 데이터를 매핑하는 거죠. Icon은 widget과 동일한 레이어에 위치시키거나 혹은 shared/icon 같은 폴더를 만들어서 유지시켜도 좋았을 것 같네요! 여하튼 정리하자면, 디자인시스템을 생각해 보시면 좋은데요, 디자인 시스템은 다양한 UI의 단위를 만들어서 제공하고 있어요. 현재 과제에서도 Table과 TableItem 혹은 Tr이라는 UI 요소를 추출할 수 있지 않을까!?라는 생각이 드네요! 물론 이를 랩핑 해서 사용하는 영역은 features 혹은 widgets가 맞다고 적절하다고 생각합니다 ㅎㅎ

위에 남긴 건 저의 생각일 뿐이고, 결국 제일 중요한 건 민기 님의 생각이라고 생각해요. 누군가가 "이렇게 코드를 작성한 이유가 있나요?" 라고 물어봤을 때 다른 사람의 생각을 기반으로 민기님의 생각을 전개하려고 하면 결국 말문이 막히게 된답니다. 민기 님이 왜 이렇게 생각하게 되었는지에 대해 촘촘하게 고민해 보시면 좋겠어요!

 

나름 내 생각이 맞았다고 한 부분이 있어서 너무 좋았다. 물론 준일 코치님의 위의 내용을 또한 테오가 만드신 코드도 어느 정도 봤는데 나의 생각과 많이 비슷한 부분이 있어서 나름 뿌듯했고, 나만의 확립 기준을 가지고 컨벤션에 맞게 진행하는 게 중요하다 생각한다. 

 

결론

테오나 준일코치님이 말했듯이, FSD 아키텍처는 사용자의 사용하기 나름이라 정답은 없는 거 같다. 대신 위에서 언급했지만 중요한 것은 저것을 사용할 때 모든 팀원들이 똑같이 컨벤션을 맞추는 게 중요하다고 말씀 주셨다. 밑의 URL은 FSD 관련내용으로 참고하여 보면 좋을 것 같다. 

https://velog.io/@teo/fsd

 

FSD 관점으로 바라보는 코드 경계 찾기

이번 글의 주제도 FSD(Feature-Slided Design)입니다! 현재 제가 가장 관심있는 관심사 2가지 중 하나가 바로 이 FSD 네요. 지금 하고 있는 일이 레거시 코드를 최신 기술로 고도화하는 작업입니다. 그러

velog.io

https://velog.io/@teo/folder-structure

 

폴더구조의 변화로 이해하는 프론트엔드 멘탈모델 변천사

...솔직히 FSD(Feature Sliced Design)를 프로젝트에 도입해보려 했는데, 이론적으로는 그럴듯해 보이지만 막상 해보면 오히려 복잡성만 가중시키는 느낌입니다. feature와 entity의 경계도 애매한 경우가

velog.io

https://feature-sliced.design/docs/reference

 

 

5주차 프로젝트

5주차 프로젝트는 디자인 패턴과 함수형 프로그래밍에 대한 것이였다. 여러 디자인패턴에 대해 알아보고, 각각의 장단점을 비교해보는 것이였다. 

 

문제

기본과제는 더러운 코드를 리팩토링하여, props 가 많아짐에 따라 불편함을 느끼고, hook과 전역 상태 관리를 통해 Props Drilling을 줄이는 것이다. props가 많아짐에 따라, 의존성도 많아지고 재사용성이 급격하게 줄다보니 안좋아지는 장점이있었다. 

 

(이전)

(이후)

 

그리고 계산과 액션 데이터를 분리하는 것이 문제여서 어떤식으로 나눌지 고민이 많았는데, 발제 자료를 보며. 정리하였고 React에서 액션과, 계산, 데이터를 분리하기 위한 내용은 다음과 같다.

 

React에서 액션, 계산, 데이터분리전략

  • 데이터: props와 state
  • 계산: 순수함수, 컴포넌트, 렌더링로직
  • 액션: 이벤트 핸들러, 부수효과 (useEffect 등

 

또한 컴포넌트에도 계층이 있다는 것을 처음알어 이 기회에 정리하여 밑의 URL에 정리하였다. 

https://github.com/jeongmingi123/front_6th_chapter2-2/issues/1

 

컴포넌트의 종류 · Issue #1 · jeongmingi123/front_6th_chapter2-2

서론 컴포넌트의 계층을 파악하고 이해하려고 노력했는데 맞는지는 모르겠다. 이 기회에 컴포넌트 종류를 정리하려고 한다. 내가 이해한게 맞다면 컴포넌트의 종류들은 다음과 같다. UI 컴포넌

github.com

 

 

결론

각자 책임에 맞게 역할을 분리하는 게 정말 어려웠다. 또한 계산, 데이터, 액션을 나누는 방법을 몰라서 좀 많이 어려웠다.

그나마 다행인건 함수형코딩을 예전에 책을 사놔서 예전에는 몰랐는데 다시 봐보니 색다른 것같다. 시간될때마다 정리를 해야겠단 생각이 든다. 

 

함수형 프로그래밍 

 

쏙쏙 들어오는 함수형 코딩 | 에릭 노먼드 - 교보문고

쏙쏙 들어오는 함수형 코딩 | 함수형 개발자는 어떻게 생각하고 코드를 작성할까함수형 프로그래밍은 절차적 프로그래밍, 객체 지향 프로그래밍과는 다른 새로운 방식의 프로그래밍이다. 따라

product.kyobobook.co.kr

 

오늘 궁금한 것

  • 전역 상태 관리는 어떤식으로 써야할까? 
    • User, Modal과 같은 컴포넌트 관리할때는 좋음. 
    • But Props Drlling이 어느정도 기준에 따라 전역 상태 관리를 써야할까..? (아직 해결 X)
  • hooks를 만들 때, handle은 hooks로 나눠야할까??
    • 아직 해결 X

 

이력서 피드백

오늘 채영님, 지현님, 소연님에게 이력서를 보여드렸고, 이력서의 부족한부분에 대해 다음과 같이 작성하도록 말씀주셨다.

  • 프론트 프로젝트 위에 적기
       * SMAR 기법
       * 상세하게 적기
  • 기존 경력은 아래로 내리고 / 프론트 관련 프로젝트 경험 위로 올리기
  • 단순히 해결했다 X. 문제해결 노력한내용 적기 O
       * 어필 많이하기 이 일은 회사에서 꼭필요했고 입증이 되었다. 
  • 어떻게 적어야할지 모르겠다면.. 상세하게 적고 일단 단어뺄거 컨펌 받기
  • 자기소개 불릿 형태로 바꾸기 

서론

이번 주차는 레거시한 코드를 Clean Code 원칙에 맞게 미션을 완주하는 것이다. 사실 이번 과제는 정답은 없어서 주관적인 느낌도 조금 들어간다. 목표는 유지보수 쉽게 하고, 잘게 나눠서 테스트를 용이하도록 만드는 게 목표다.

 

본론

사실 내가 좀 어려웠던 것은 단일 책임에 맞게 코드를 짜는게 좀 어려웠다. 또한 사이드 이펙트를 어떻게 줄일까에 대한 고민이 많았다. 

화요일 보너스 관련 코드인데, 함수안에서 new Date()를 직접 호출하여, 현재 시간에 의존하게 되어 사이드 이펙트가 발생하였다.

 

이전

export function applyTuesdayBonus(basePoints: number): number {
  const today = new Date();
  const isTuesday = today.getDay() === 2;
  return isTuesday ? basePoints * 2 : basePoints;
}

 

이후

const TUESDAY = 2;

export function applyTuesdayBonus(basePoints: number, date: Date = new Date()): number {
  const isTuesday = date.getDay() === TUESDAY;
  return isTuesday ? basePoints * 2 : basePoints;
}

 

그리하여 사이드 이펙트를 줄이고자 date 매개 변수를 추가하여, 날짜를 외부에서 주입할 수 있게 하여 사이드 이펙트를 줄였다. 또한 테스트 케이스도 작성 가능할 수 있도록 줄였으며, 매직넘버를 제거하여 좀 더 의미 있는 코드로 만들었고, 값의 리렌더링을 방지를 위해 상수값을 밖으로 빼냈다. 

 

그리고 프로젝트내의 Service 폴더와 Util 폴더의 역할이 사실 궁금했었다.

Service 폴더는 항상 fetch와 같은 api 통신을 위해 사용했었다. 하지만 이전에 과제를 하면서 localstorage와 같은 로직을 저장하거나 사용할 때, Service폴더에 넣길래.. 음? 백엔드가 api가 없어서 임시로 mock 데이터를 사용하다 보니 Service 폴더에 넣는 건가?라는 생각을 했었다. 

 

// 기본 포인트 계산 (구매액의 0.1%)
export function calculateBasePoints(totalAmount: number): number {
  return Math.floor(totalAmount / 1000);
}

// 화요일 포인트 배수 적용
export function applyTuesdayBonus(basePoints: number, date: Date = new Date()): number {
  const TUESDAY = 2;
  const isTuesday = date.getDay() === TUESDAY;
  return isTuesday ? basePoints * 2 : basePoints;
}

// 특정 제품이 장바구니에 있는지 확인
function hasProductInCart(cartItems: CartItem[], productList: Product[], productId: string): boolean {
  return cartItems.some((item) => {
    const product = productList.find((p) => p.id === item.productId);
    return product && product.id === productId;
  });
}

// 키보드+마우스 세트 보너스 계산
function calculateKeyboardMouseBonus(cartItems: CartItem[], productList: Product[]): BonusResult {
  const hasKeyboard = hasProductInCart(cartItems, productList, PRODUCT_IDS.KEYBOARD);
  const hasMouse = hasProductInCart(cartItems, productList, PRODUCT_IDS.MOUSE);

  if (hasKeyboard && hasMouse) {
    return { bonus: 50, detail: '키보드+마우스 세트 +50p' };
  }

  return { bonus: 0, detail: '' };
}

위의 코드는 단순 계산을 하기에 나는 util 폴더에 넣어야지~ 했는데 알고보니 지훈 님과 가은님에게 여쭤보니까.. 알고 보니 Service 폴더는 도메인 로직을 담당하는 곳이었다. 그리고 util 폴더는 오늘 발제시간에 팀 페어 활동 중 말씀 주셨는데, 어느 곳에서나 사용하는 공통 함수를 넣기 위해 사용하는 것이었다. 

하 너무 궁금한 부분들이 많아 해결되어 기분이 좋다.. 가은님, 지훈님, 지현님에게 너무 감사드립니다..

 

결론 

멍청한나였고... basic에서 -> react typescript로 변경하면서 그냥 지워도 되는 건 줄 알고.. basic 기존에 코드 짰던 거 모르고 다 지워버렸다.. 그냥 테스트 깨져도 되는 건 줄 알았음.. 그래도 basic 리팩토링 했다는 것에 만족한다... ㅜㅜ

그리고 .. 궁금한 것은 너무 쌓아두지말고 많이 질문해야겠다..

 

+ Recent posts