블로그

유진

인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 1주차

강의 출처 Readable Code: 읽기 좋은 코드를 작성하는 사고법 학습 내용읽기 좋은 코드를 작성하기 위해서는 추상화가 필요하다.추상화의 방법변수와 메서드의 이름에서 무엇을 하는지 알 수 있어야 한다.메서드 시그니처(메서드명, 파라미터), 반환타입추상화 레벨을 동등하게 해주어야 한다.상수 추출early return중첩 분기문, 중첩 반복문 줄이기부정어구를 대체 할 수 있는지예외처리(개발자가 의도한 예외와 예상치 못한 예외의 처리)NullPointException, Optional객체지향SOLID미션추상과 구체의 예시 : 카페에서 커피를 주문하는 것을 단계별로 구체화했다.코드 리팩토링 : 메서드명 변경, 메서드 추출, early return, 부정어구 대체 등을 하여 코드를 리팩토링 했다.SOLID 나만의 언어로 정리 회고클린코드에 대해 어떻게 접근해야 할 지 알 수 있어서 좋았다. 막연하게 어렵다고 생각했던 것들을 코드 리팩토링을 통해 공부할 수 있어서 좋았다. 그런데 생각보다 강의를 듣는게 빠듯했다. 강의만 듣는 것이 아니라 직접 코드로 적용해 보려고 하니까 강의 시간의 두 배는 더 소요되는 것 같다. 게다가 2번째 미션은 시간 안에 제출하지 못했기 때문에 다음 주부터는 시간 분배를 잘해야겠다.  

백엔드인프런워밍업클럽2기백엔드

김체토

[인프런 워밍업 클럽 2기] 프로덕트 디자인 1주차

 1주차 발자국 기록 지난 인프런 워밍업 클럽에 이어서 2번째로 참여하게 되었습니다.1기 때 양이 너무 많아서 힘들긴 했지만.. 그래도 워밍업 클럽 덕분에 완강과 실습을 모두 해낼 수 있었다고 생각합니다. 이번에는 복습 겸 BX를 담아 체계적으로 만들어보려고 합니다. 더 나아가서 개발자분들과도 협업하여 디자인 시스템을 만들 수 있으면 그 부분까지 확장시켜볼 계획입니다. - 이번 주 기록 ☑ 디자인 토큰이란?- 디자인 토큰은 전자에 해당- 디자인 시스템의 기본 구성 요소- 작고 반복 가능할 수 있는 디자인 결정들을 기본 디자인 에셋으로 저장해서 활용- 토큰은 디자인 시스템 관리와 수정에 용이하고 일관성 및 멀티 브랜드 관리에 도움 ☑ 디자인 시스템이란?재사용 가능한 컴포넌트, 패턴 그리고 가이드 🪄 추천 플러그인 : Styles to variable- 스타일을 배리어블로 만들어줌- collection 이름을 정할 수 있음https://www.figma.com/community/plugin/1253669344925342575 🪄 홈페이지 : batch styler- 스타일 일괄 수정할 수 있음https://www.figma.com/community/plugin/739825414752646970  - 회고 이번 주는 회사에 적응하느라 하루 이틀씩 밀렸습니다.주말까지 채워서 작업을 진행했는데 다음 주는 매일 조금씩 해 보도록 하겠습니다.

UX/UIuxuifigma피그마프로덕트디자인볼드배리어블

윤재헌

[워밍업 클럽 스터디 2기 - 백엔드 클린 코드] 1주차 발자국

학습 내용추상화생략할 정보와 의미를 부여하고 드러낼 정보를 구분잘 쓰여진 글이라면, 한 문단의 주제는 반드시 하나다.잘 쓰여진 코드라면, 한 메소드의 주제는 반드시 하나다.하나의 세계 안에서는, 추상화 레벨이 동등해야한다.매직 넘버, 매직 스트링의미를 가지고 있으나, 상수로 추출되지 않은 숫자, 문자열상수 추출로 이름을 짓고 의미를 부여함으로 가독성과, 유지 보수성 상승읽기 좋은 코드코드를 읽을 때, 불필요한 정보를 기억하며 읽지 않아도 되는 코드Early Return조건이 되는 경우를 먼저 return 하여 이후 조건문을 더 간결하게 파악 가능중첩문 줄이기3중 for-loop보다 함수로 나누어 표현하는 것이 가독성이 좋아짐무조건 메소드로 나누는 것이 가독성이 좋아지는 길은 아님변수는 사용하는 위치에 가깝게공백 라인을 사용하여 문맥을 나누어 주기부정어(!)대신 메소드 자체가 부정어를 포함하여 작성예외처리의도한, 의도치 않은 예외를 구분NullPointerException을 항상 방지OptionalorElse와 orElseGet의 차이orElse: 호출할 필요가 없는 경우에도 실행orElseGet: null일 경우만 실행객체 지향캡슐화, 추상화,상속,다형성관심사의 분리높은 응집도, 낮은 결합도객체의 책임1객체는 1개의 관심사로 명확하게 정의가 되었는가setter 사용 자제getter는 필요한 경우에만 SOLIDSRP: 단일 책임 원칙 (Single responsibility principle)한 클래스는 하나의 책임만 가져야 한다.OCP: 개방-폐쇄 원칙 (Open/closed principle)소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.LSP: 리스코프 치환 원칙 (Liskov substitution principle)프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.ISP: 인터페이스 분리 원칙 (Interface segregation principle)특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.DIP: 의존관계 역전 원칙 (Dependency inversion principle)프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다.개인적인 정리 (Day 4 Mission)https://www.notion.so/hunyoon/Day-4-Mission-Readable-Code-114f5e6cf89780238071c834a0ce502a?pvs=4  상속과 조합상속보다는 조합(인터패이스)를 사용하는 것이 유연한 대처가 가능VO기본 타입을 객체로 감싸 의미를 부여하여 추상화하는 기법도메인의 어떤 개념을 추상화하여 표현한 값 객체값으로 취급하기 위해, 불변셩, 동등성, 유효성 검증등을 보장해야 한다.불변셩: final 필드, setter 금지동등성: 서로 다른 인스턴스더라도, 내부의 값이 같으면 같은 객체로 취급 (equals(), hashCode() 재정의 필요) (≠ 동일성)유효성 검증: 객체가 생성되는 시점에 값에 대한 유효성을 보장하기VO vs EntityEntity식별자가 존재식별자가 아닌 필드의 값이 달라도, 식별자가 같으면 같은 객체로 취급VO내부의 모든 값이 같아야 동등한 객체로 취급개념적으로 모든 필드가 식별자 역할을 한다고 봐도 됨 회고정말 오랜만에 스스로 앉아 일 이외의 코드를 만지는 시간이었다. 귀찮고 피곤하기만 해 멀리하기만 했던 공부지만 붙잡고 하다보니 흥미도 다시 생기고 더 잘 해내고 싶은 오기도 생기기도 했다. 연휴도 겹치고 회사 일도 있다보니 일정이 미뤄진게 많이 안타까웠다. 진도만 채우는 학습보다는 다시 곱씹어 보는 학습을 하고 싶어졌다.미션을 진행하며 그동안 정말 애매했던 추상화를 다른 방식으로 풀어보게 되었는데 매번 일상에 적용되는 일을 적용시키니 더 의미가 와닿는 느낌이었다. 두번째 미션은 직접 코드를 리팩토링 해보는 것이 었는데 학습한 내용중 가장 먼저 떠오르는 작업부터 적용시킨 후, 내가 정리해둔 문서를 보며 더 진행하니 학습한 내용이 더 내것이 되는 느낌이었다. SOLID에 대해 "내 언어"로 표현하는 부분은 여러번의 말보다 한번의 예시가 나중의 나를 위해서라도 좋다고 생각하여 각 항목의 예시를 하나씩 작성하였고 주위 지인에게도 전달하였는데 호평을 받았다.ㅎ 이 글을 작성하면서도 아직 진도가 끝나지 않아 계속 듣고 있는데 매일 시간을 내서 공부를 하시는 분들 진짜 대단하신거같다

백엔드

[워밍업 클럽 스터디 2기] 1주차 발자국

1주차 강의새로 안 부분 정리부정어를 대하는 자세부정어구를 쓰지 않아도 되는 상황인지 체크부정의 의미를 담은 또 다른 단어가 존재하는지 확인정 없으면 doesNot 사용하지만 최대한 고민해보도록.. 해피케이스와 예외처리예외를 발생할 가능성 낮추기equals 등 비교 할 때 미리 선언 된 상수를 먼저 비교하여 Null Point Error 방지하기Optional에 대하여 따로 빼서 다시 공부해보기SOLID 정리SRP: 단일 책임 원칙클래스는 하나의 책임만 가져야 하며, 해당 책임을 완수하는데만 집중해야한다.→ 클래스의 역할이 명확이 구분되어 있어햐 하며, 클래스를 변경할 이유가 하나여야 한다.이메일 전송 시스템이라면, 사용자의 정보를 저장하는 로직과, 이메일 전송 로직은 구분되어야 한다.OCP: 개방-폐쇄 원칙확장에는 열려있지만, 수정에는 닫혀있어야 한다.→ 새로운 요구사항이 생기면, 기존의 코드를 수정하지 않고도 기능을 추가할 수 있어야 한다.예시로 자주 나오는 전기자동차와 기름자동차…LSP: 리스코프 치환 원칙서브타입은 그 부모타입으로 대체할 수 있어야 하며, 프로그램의 정확성을 해치지 않아야 한다.부모 클래스의 인스턴스를 자식클래스의 인스턴스로 치환할 수 있어야한다.→ 자식 클래스는 부모 클래스가 정의한 행동을 해치지 않아야 한다.추상 : 새는 난다. 새는 소리를 낸다.구현: 참새는 난다. 참새는 짹짹 소리를 낸다비둘기는 난다. 비둘기는 구구 소리를 낸다…ISP: 인터페이스 분리 원칙클라이언트는 사용하지 않는 메서드에 의존해서는 안된다.→ 하나의 일반적인 인터페이스보다 여러개의 구체적인 인터페이스로 구현하는데 대부분 좋다.DIP: 의존 역전 원칙고수준 모듈은 저수준 모듈에 의존해서는 안되며, 둘 다 추상화에 의존해야 한다.→ 구체적인 클래스 보다는 인터페이스나 추상 클래스에 의존해야 한다.  인프런 워밍업 클럽 2기(백엔드 클린코드, 테스트코드) -https://www.inflearn.com/course/offline/warmup-club-2-be-wb강의 출처 -https://www.inflearn.com/course/readable-code-읽기좋은코드-작성사고법

예은

[인프런 워밍업 클럽 2기] 프로덕트 디자인 1주차

볼드UX 튜터님의 <피그마 배리어블을 활용한 디자인 시스템 구축하기>를 수강하며 인프런 워밍업 클럽에 참여하게 되었다.프로젝트들을 진행하며 디자인 시스템을 구축하는 능력이 필요하다는 것을 느끼고 있었다.... 특히 원활한 소통을 위해서 꼭 공부하고 싶다고 생각했다.그리고 사실, 전부터 눈독 들이던 강의였기에 더욱 열의가 넘쳤다!매일매일 학습하는 커리큘럼이라 진도를 잘 따라갈 수 있을지 살짝은 걱정됐지만... 하고 싶은 일이니 열심히 할 수밖에 없다!일단 시작하고 될때까지 하면 된다. 레츠고 배움디자인 토큰과 디자인 시스템에 대한 이해배리어블과 스타일 학습다양한 배리어블 등록 미션컬러, 타이포그래피, 간격, 효과 등 배리어블 등록그리드와 반응형 기준점, 아이콘 등록작업한 스타일 가이드 문서화 (수줍은 탓에 과제물은 모자이크처리해 올립니다...) 이건 꼭 알아두자배리어블 vs 스타일저장 가능한 변수값의 개수: 하나 / 하나 이상참조 여부: 참조 가능 / 참조 불가능모드 여부: 모드 활용 가능 / 직접적인 활용 불가능배리어블 => 다양한 모드에서 달라지는, 재사용 가능한 색상을 등록하는 경우스타일 => 여러 디자인 요소 결합해 사용하는 경우 회고스스로 칭찬하고 싶은 점개인적으로 학습 분량이 벅차게 느껴졌지만 포기하지 않고 어떻게든 해냈다.다른 분들의 작업물을 둘러보며 스스로의 개선점을 찾아보았다. 아쉬웠던 점아직까지 학습이 습관화되지 않은 것 같다. 개선 필요보완하고 싶은 점계획을 세워 여유롭게 학습할 수 있는 환경을 조성하고 싶다.다음주에는나만의 규칙을 만들어 일정한 시간에 학습할 것이다.단순히 멘토님을 따라 학습하는 것에서 더 나아가, 스스로 고민해보고 디자인 시스템을 구축할 것이다. 

UX/UIUXUI피그마프로덕트디자인볼드UX

[워밍업 클럽 스터디 2기 - 클린코드, 테스트코드] 1주차 발자국

섹션2. 추상클린 코드를 왜 지켜야 할까?가독성이 좋다 = 코드가 잘 읽힌다 = 이해가 잘 된다 = 유지보수 하기가 수월하다결국 나와 팀 전체가 유지보수 하기가 수월하기 때문에 클린 코드를 지향해야 한다.추상적 사고란?표현하고자 하는 구체에서 핵심 개념만을 추출하여 잘 드러내는 표현도메인의 문맥 안에서 이해되는 용어변수, 메서드 이름, 매직 넘버, 매직 스트, 추상화 레벨을 맞춰 읽기 좋게 만듦 섹션3. 논리, 사고의 흐름void 대신 반환 타입 주기 -> 반환값이 있으면 테스트 용이early return을 통한 else 사용 지양사용 변수는 가깝게공백을 통한 의미 나누기부정연산자 사용 대신 의미를 변경해피 케이스와 예외 처리 섹션4. 객체 지향 패러다임객제 지향의 장점절차 지향에서 잘 보이지 않았던 개념을 가시화관심사가 한 군데로 모여 유지 보수성을 높임보다 높은 추상화 레벨에서 도메인 로직 다룸 주의! Setter 사용 자제: 데이터는 불변이 최고Getter 사용 자제: 객체에 메시지를 보내라!1개의 관심사로 명확하게 책임이 정의되었는지 확인하기  SOLIDSRP: 하나의 클래스는 단 한 가지의 변경 이유만을 가져야 한다. OCP: 확장에는 열려 있고, 수정에는 닫혀 있어야 한다. LSP: 상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다. ISP: 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다. DIP: 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 모두 추상화에 의존해야 한다.  1주차 미션Day2 미션흑백 요리사를 보던 중 백종원 선생님이 음식을 맛있게 먹는 평가하는 모습을 보고 이를 구체적으로 표현해 보았다.음식을 먹는다.음식 속 맛을 내는 물질이 입안으로 들어온다.침에 녹아 맛 구멍을 통해 들어간다.맛을 감지하는 세포가 자극을 받는다.자극이 신경을 통해 뇌로 전달된다.맛을 느낀다.맛을 평가한다.  Day4 미션주어진 코드를 클린 코드 방식으로 리팩토링 하였다.SOLID에 대해 복기하며 다시 정의해 보았다. 1주차 회고병행하는 게 많아서 강의 진도를 따라가기 힘들었다.클린 코드에 대해 막연히 생각했었는데, 이번 기회에 잘 배워서 내 것으로 만들 수 있도록 해야겠다.   

백엔드

야나

[미션] 인프런 워밍업 클럽 2기 CS - 1주차

 운영체제1. 아래 코드는 1초 마다 플레이어가 스킬을 사용했는지 체크하는 코드입니다. 이 방식은 폴링방식입니다. 1초마다 체크하기 때문에 성능에 좋지 않습니다. 이를 해결하기 위한 방식으로 어떤 걸 이용해야 할까요? while(true){ wait(1); // 1초 멈춤 bool isActivated = checkSkillActivated(); // 체크 }폴링 방식 대신 인터럽트 방식을 사용하면 성능을 개선할 수 있습니다. 인터럽트는 특정 조건이 발생했을 때, CPU가 그 일을 처리하게 만드는 방식이기 때문에 예를 들어, 플레이어가 스킬을 사용했을 때만 인터럽트가 발생하도록 해서 CPU가 불필요하게 1초마다 체크하지 않도록 할 수 있습니다.2. 프로그램과 프로세스가 어떻게 다른가요?프로그램 : 저장된 명령어의 집합, 실행 파일 형태로 하드디스크나 메모리에 존재하지만 실행되지 않은 상태.프로세스 : 실행 중인 프로그램으로, 운영체제가 관리하는 실행 단위. CPU 시간과 메모리 같은 자원을 차지하며 활동 중임.3. 멀티프로그래밍과 멀티프로세싱이 어떻게 다른가요?멀티프로그래밍: 메모리에 여러 프로그램을 올려두고, CPU가 한 번에 하나의 프로그램을 처리하지만 빠르게 교체하며 실행하는 방식.멀티프로세싱: 여러 CPU 또는 코어가 동시에 여러 프로세스를 병렬로 실행하는 방식으로, 물리적으로 병렬 처리가 이루어짐.4. 운영체제는 프로세스를 관리하기 위해서 어떤 것을 사용하나요?운영체제는 프로세스 제어 블록(PCB, Process Control Block)을 사용해서 프로세스를 관리합니다. PCB는 운영체제가 각 프로세스의 상태와 관련된 중요한 정보를 저장하는 자료구조이며, 운영체제는 이 정보들을 기반으로 CPU 스케줄링, 메모리 관리, 입출력 관리를 수행합니다.5. 컨텍스트 스위칭이란 뭔가요?컨텍스트 스위칭은 운영체제가 한 프로세스의 실행 상태를 저장하고, 다른 프로세스의 상태를 복구해 CPU에서 실행을 전환하는 과정입니다. 이때 프로세스의 레지스터, 메모리, 스케줄링 정보를 저장하고 복구합니다.자료구조와 알고리즘1. 여러분은 교실의 학생 정보를 저장하고 열람할 수 있는 관리 프로그램을 개발하려고 합니다. 이 때 여러분이라면 학생의 정보를 저장하기 위한 자료구조를 어떤 걸 선택하실 건가요? 이유를 함께 적어주세요.해시테이블 : 해시테이블은 학생의 고유한 식별자(예: 학번, 이름 등)를 키로 사용하여 해당 학생 정보를 저장하고 빠르게 검색할 수 있습니다. 평균적으로 O(1)의 시간 복잡도로 접근이 가능해서 대규모 학생 정보를 빠르게 처리할 수 있다는 장점이 있기때문에, 학번이나 이름으로 학생을 조회하는 작업에 적합하다고 생각합니다.2. 여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다. 주문은 들어온 순서대로 처리됩니다. 이 때 여러분이라면 어떤 자료구조를 선택하실 건가요? 이유를 함께 적어주세요.큐 : 주문은 들어온 순서대로 처리되기 때문에 FIFO(First In, First Out) 방식이 필요하기 때문에 FIFO 로 데이터가 처리되는 큐가 주문처리를 위한 자료구조 적합하다고 생각합니다.

알고리즘 · 자료구조알고리즘자료구조배열연결리스트스텍해시테이블

세지

워밍업클럽CS2기 1주차 미션

 운영체제 1.while(true){ wait(1); // 1초 멈춤 bool isActivated = checkSkillActivated(); // 체크 }위 코드는 1초 마다 플레이어가 스킬을 사용했는지 체크하는 코드입니다. 이 방식은 폴링방식입니다. 1초마다 체크하기 때문에 성능에 좋지 않습니다. 이를 해결하기 위한 방식으로 어떤 걸 이용해야 할까요?폴링 방식 단점을 해결한 인터럽트를 활용합니다. 인터럽트란 CPU가 명령을 내리고 작업이 완료되면 신호를 받아 인터럽트 서비스 루틴을 실행시켜 작업을 완료합니다. 비동기적으로 동작하여 성능에 이점이 있습니다.  2. 프로그램과 프로세스가 어떻게 다른가?프로그램은 저장장치에 저장된 명령문의 집합체로 저장장치만 사용하는 수동적인 존재입니다. 프로세스는 하드디스크에 저장된 프로그램이 메모리에 올라간, 실행중인 프로그램을 말하며 CPU 사용과 입출력도 수행할 수 있는 능동적인 존재입니다. 멀티프로그래밍과 멀티프로세싱이 어떻게 다른가?멀티프로그래밍은 메모리에 여러개의 프로세스가 올라와있고, 멀티프로세싱은 CPU가 여러 개의 프로세스를 처리합니다.멀티프로그래밍은 메모리에 여러 개의 프로세스가 실행 중인 상태를 말하고, 멀티 프로세싱은 CPU가 여러 개의 프로세스를 처리하는 것을 말합니다.  운영체제는 프로세스를 관리하기 위해 어떤 것을 사용하는가?프로세스가 만들어지면 운영체제는 해당 프로세스의 정보를 가지고 있는 PCB(Process Control Block)를 만들고 저장합니다. 연결리스트라는 자료구조로 저장되고 프로세스가 종료되면 연결리스트에서 해당 프로세스의 PCB를 제거합니다. 5. 컨텍스트 스위칭이란 무엇인가?프로세스 실행 중 다른 프로세스를 실행하기 위해 실행 중인 프로세스 상태를 저장하고 다른 프로세스의 상태 값으로 교체하는 것을 말한다. CPU 점유시간이 끝났거나, I/O 요청이 있거나 인터럽트가 있을 때 등 발생한다.    자료구조와 알고리즘 여러분은 교실의 학생 정보를 저장하고 열람할 수 있는 관리 프로그램을 개발하려고 합니다. 이 때 여러분이라면 학생 정보를 저장하기 위한 자료구조를 어떤 걸 선택하실 건가요? 이유를 함께 적어주세요.보통 교실의 학생 수는 정해져 있으나, 전학이나 자퇴 등의 사유로 인원 수가 변동될 수 있습니다. 하지만 그 횟수가 빈번하지 않고 데이터의 삽입, 삭제보다는 주로 참조 용도로 쓰일 것으로 생각되어 배열이 적당하다고 판단됩니다. 여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다. 주문은 들어온 순서대로 처리됩니다. 이 때 여러분이라면 어떤 자료구조를 선택하실 건가요? 이유를 함께 적어주세요.들어온 순서대로 주문을 처리하고, 주문이 변경이나 취소되는 경우를 고려하여 이중연결리스트를 활용한 큐 적당하다고 생각합니다.

알고리즘 · 자료구조인프런워밍업클럽운영체제자료구조와알고리즘인프런워밍업클럽미션CS

[워밍업 클럽 2기 - Clean Code & Test Code] 1주차 발자국

워밍업 클럽 2기: Clean Code & Test Code의 1주차 발자국 작성입니다. ✍ 학습 내용 복습 Q. 클린 코드를 작성하는 이유?미래의 나, 미래의 동료가 더러운 코드로 인해 고통 받지 않도록 하기 위해서 클린 코드를 작성한다.코드를 작성하는 순간부터 그 코드는 사실상 기술 부채를 가지게 된다. 기술 부채를 최대한 줄이기 위해서 클린 코드를 작성한다. Q. 클린 코드를 작성하기 위해서 사용하는 가장 핵심적인 개념은?추상화라고 생각한다. 추상화의 본질은 핵심 개념만 드러내고, 불필요한 정보는 감추는 것이다.추상화 레벨이 높아질수록 더 함축적인 개념을 다루고, 낮아질수록 구체적인 동작과 세부 구현에 집중한다.추상화 레벨이 높아지면 높아질수록 정보의 함축 수준이 높아지고 이해하기 쉬워진다. 그렇다고 너무 함축시키면 실제 구체(정보)의 재현이 어렵기 때문에 적절한 추상화가 필요하다. Q. 적절한 추상화란?적절한 추상화란 해당 도메인 내에서 핵심적인 부분만 드러내면서 구체적인 구현은 필요에 따라 숨기는 것이다핵심적인 부분과 불필요한 정보의 구분은 문맥에 따라 언제든지 달라질 수 있다도메인을 파악하는 것이 중요하다 Q. 효과적인 네이밍은?네이밍(이름짓기)을 통해서 의도를 드러낼 수 있다. 높은 추상화 레벨에서는 세부 사항을 숨기고, 큰 개념을 드러내는 네이밍을 사용한다. 낮은 추상화 레벨에서는 더 구체적인 동작을 설명하는 이름을 사용한다.대부분의 경우 내부로 들어갈수록 추상화 레벨이 낮아진다주변 코드와의 추상화 레벨이 동떨어져 있는지 지속적으로 확인하는 것이 좋다 Q. 가독성이 좋은 코드는?가독성이 좋은 코드는 불필요한 정보를 덜 인지 해도 되면서 이해하기 수월한 코드라고 생각한다. Q. 가독성이 좋은 코드를 작성하는 방법들은?early return 사용하기이중 반복문, 분기문의 depth를 줄일 수 있는지 고민하기부정어 표현 !을 제거할 수 있는 방법이 있는지 고민하기 Q. 객체란?캡슐화비공개 데이터(필드), 비공개 로직(프라이빗 메서드)을 가질 수 있다공개 메서드를 통해서 외부와 소통한다객체 간 상호작용(협력)을 한다하나의 객체로 관심사가 모이기 때문에 유지보수하기 쉬워진다 Tip. 객체 사용시 주의점하나의 관심사를 가지는지 확인하자웬만하면 setter의 사용을 자제하고, 값의 변경은 updateXxx, addXxx 같은 명확한 네이밍을 사용하자 Q. SOLID(객체 지향 설계의 5개 원칙)는 무엇인가?https://www.inflearn.com/blogs/8391 에 정리 Q. 상속 보다 조합을 권장하는 이유는?상속 관계에서 자식과 부모간의 결합은 매우 강하다. 이는 부모 클래스의 변경은 자식 클래스에도 영향을 준다는 의미이다. 변경의 가능성이 매우 적고, 상위 클래스의 활용이 필요한 경우가 아니라면 조합과 인터페이스의 사용이 훨씬 유연한 구조를 제공한다 🤔 회고코드를 같이 따라치면서 학습하는 것이 더 효율적일 것 같다. 주말 동안 코드도 같이 따라 치면서 복습할 생각이다.토이 프로젝트에 배운 내용을 직접 적용해보면서 학습할 예정이다. 참고Readable Code: 읽기 좋은 코드를 작성하는 사고법

백엔드워밍업클럽2기백엔드클린코드-테스트코드발자국1주차

[워밍업 클럽 스터디 2기::백엔드] 1주차 발자국

1주차 클럽 스터디 회고이번주 학습 내용추상화의 개념은 중요한 정보를 가려내고 덜 중요한 정보를 제거하여 도메인 내에서 명명한 항목을 보고 어떤 행위, 어떤 정보를 담고 있는지 파악 가능하도록 하는것 읽기 좋은 코드를 작성하기 위해서 신경써야 할 부분추상화할 때, 하나의 책임으로 묶기 어려울 경우, 여러 부분으로 나눠야 한다.어떤 항목의 이름을 지을때, 단수와 복수를 구분해서 사용하고, 이름을 줄이지 않으면서 명명해야 한다.메소드의 이름을 지을 경우, 메소드 시그니처 (메소드 명 + 파라미터)를 통해 어떤 정보를 가지고 어떤 행위를 하는지명확하게 표현할 수 있도록 해야한다.** 한 파일 안에서, 추상화 레벨이 동등하게 (자연스럽게 읽으면서 지나갈 수 있도록) 구성해야 한다.상수를 사용할 경우, 매직 넘버/스트링 과 같이 이름을 짓고 사용해야 한다.Early return 을 사용해 else if/else 의 사용이 꼭 필요한 경우가 아닌 경우 지양해야 한다.사용할 변수는 가깝게 선언해야 한다.!사용을 피하고 반대되는 사항이 있을경우 반대되는 의미를 담도록 명명하고, 반대되는 의미가 여러개일 경우 부정어를 통해 명명하는 것이 좋다.의도한 예외와 예상하지 못한 예외를 구분해서 관리해 예상하지 못한 예외를 분석을 통해 줄여가야한다.객체지향 프로그래밍을 제대로 활용하기 위해 SOLID 원칙을 지켜가며 고민해가면서 설계해야 한다.  좋았던점 (Liked) 모든 강의를 들으면서 파악한 내용들을 Notion 에 기록했다. 회고록, 강의에 대한 과제를 진행하거나, 내가 내용을 정리할 때 내가 적은 내용을 보고 기억을 떠올리기 좋았다.  실무에 적용을 해보았다. 회사에서 진행하는 프로젝트에서, 한 도메인에서 호출하는 함수들이 자연스럽게 읽으면서 지나갈 수 있도록 메소드 명들을 변경해봤으며, 결과물을 보았을 때 뿌듯했다. 아쉬웠던 점 (Lacked) 스터디 일정에 맞추어 진행하지 못했다. 매번 과제 제출일이 기한 전날 저녁 6시를 넘어서 작업이 끝내서 겨우겨우 제출했다.. 매일 시간을 더 할애해서 미리미리 준비하고, 여유있게 작업할 수 있도록 해야겠다!  SOLID, stream API 등 더 궁금한 부분이 있었지만 더 조사해보지 못했다. 매번 시간에 쫓겨서 하다보니 더 궁금하고 찾아보고 싶은 부분이 있었으나, 순간 기억하고 따로 기록하지 않아서 궁금했다가 까먹은 항목이 있다. 해당 부분들을 다시 강의를 들어보며 정리하는 시간을 가질 수 있도록 해야겠다. 배운 점 (Learned) 단축키의 장점을 배워가고 있다. 매번 마우스로 이리저리 옮겨가며 작업하던 부분을 단축키를 통해 훨씬 빨리 움직일 수 있음을 배웠다. 우빈님의 강의를 따라가기 위해서 기록 이외에 단축키를 통해 이동하실 때, 나는 마우스를 써서 못따라갈 경우가 많았는데, 메소드 추출, 생성자 호출(?) 등 점점 자연스럽게 단축키 사용이 익숙해져 가고 있다.  사고를 해야하는 방식 과 무엇을 더 고민해야할지 배우고 있는것 같다. 물론 아직까지 경험도 많이 없고 미흡하지만, 어느쪽으로 고민해야하고, 어떤 경우에 분리가 필요하고, 메소드를 언제 만들어 야 할지를 조금씩 깨달아 가는 것 같다. 코드를 따라하며 어느 부분은 더 신경을 써야겠다를 내가 먼저 생각한 떄도 한 두번 있 었는데, 그때마다 너무 신기하고 기분이 좋았다. 앞으로 바라는 점(Longed for) 공부시간을 늘리고, 기록을 좀더 자세하게 해야겠다. 보통 3시간 강의를 들을때 내가 정리해가며 강의를 들으면 5시간 이상 필요한 것 같다.. 이렇게 해도 가끔 놓히는 부분이 생겼었으니, 주말에 따라갈 수 있도록 궁금한 내용을 기록하고, 많은 것을 얻을 수 있도록 노력해야겠다!    

백엔드

hyuk_lL

인프런 워밍업 클럽 2기 백앤드 프로젝트 - 1주차 발자국

8월달에 KDT 교육과정으로 백엔드 부트캠프를 수료했는데 기본기를 톺아보고 싶어서 신청했고 새로운걸 많이 알게 되어서 너무 만족스럽다더군다나 이번 스터디로 Kotlin으로 서비스를 만들고 배포까지하고 나중에는 Android + Spring server 모두 코틀린으로 만들고 운영해보고자 하는 포부를 밝힌다. 웹 개발 기본과 프로젝트 준비단계에서는 늘 해오던 부분인지라 자연스럽게 물흐르듯이 넘어갔다개발, Domain 부분에 있어서 git, github 부분에서는 무작정 CLI환경으로 명령어를 입력하고 진행했는데 색다르게 IntelliJ 환경에서 '딸깎' 으로 푸시 커밋을 쉽게 하는걸 보고 조금 놀랐다... 자주 활용하지 않을까 싶음그리고 application-properties 파일을 하나의 yml 파일에서spring.config.activate.on-profile: 별명을 통해서 사용했었는데 그냥 단순하게 파일을 나눌 수 도 있구나를 새롭게 알아서 좋다이건 개인 취향 같기는한데 파일을 나누는게 나는 더 좋아보인다그리고 부트캠프에서는 테스트 코드의 중요성을 일부 코치진께서 알려주었지만 실제로 해보지는 못했다 하지만 이 강의에서는 중요성도 알려주시고 테스트코드만 작성하는 부분도 별도로 준비되어있어서 TDD를 어느정도 공부해보고 싶던 나에게는 아주 만족스러웠다이렇게 첫번째 발자국을 간략하게 남겨보았다앞으로 남은 미션과 발자국을 쭉 작성하면서 어느정도 실력이 늘어날지 궁금하다 

Yoo Seung Hwan

[인프런 워밍업 클럽 2기 백엔드 프로젝트 과정] 1주차 발자국

참여 동기바야흐로 2024년 8월 13일 1년 6개월간의 군생활을 마치고 전역했습니다.전역 후 아직 미래에 뭘 할지 몰라서 게임 개발, 웹 개발 등등 이것저것 뚝딱이면서 시간을 보내고 있었는데... 메일함에서 발견한 인프런 워밍업 클럽2기 홍보 메일독학의 한계항상 물어볼 곳을 찾고 싶었다.아마 대부분의 초보 코딩 독학러들이 하는 고민일까 싶습니다. 강의를 듣고 내가 프로젝트를 해나가도 내가 하는 방법이 맞는 걸까? 내가 짠 코드가 쓸만한 코드인가? 누군가가 내 코드를 보고 리뷰해줬으면 좋겠고 내가 하고 있는거에 대한 피드백을 해주기를 원했습니다. 부트 캠프는 좀 힘들고...그렇다고 부트캠프나 따로 받기에는 지역도 서울 경기 지방으로 한정되어 있고 대부분 6개월 정도의 긴 기간의 대면 수업을 요구합니다. 지방대생인 저로서는 그런 부트캠프보다는 기간이 짧고 비대면인 워밍업 클럽은 최적의 조건이였습니다. 다른 사람들 생각도 좀 들어보고 싶다.아직 낯설지만 천천히 가보겠습니다.덤으로 다른 개발자들과 소통할 수 있는 창구가 생기는 것 또한 마음에 들었습니다. 다른 개발자들의 생각과 공부법에 대해 궁금한점이 많았던 저에게 워밍업 클럽은 더없이 좋은 기회라 생각하여 신청하게 됬습니다.   1주차 발자국코틀린과 백엔드에 대해 몰라도 따라갈 수 있었습니다.처음에는 코틀린과 스트링 부트에 대해 아는게 하나도 없어서 잘 따라갈 수 있을까 걱정했었는데 양질의 강의 자료와 자세한 설명덕분에 이해하기 수월했습니다. 특히 시작전에 완성된 결과물과 기능에 대해 설명해주셔서 코틀린을 잘 몰라도 코드의 의도를 파악할 수 있어서 좋았습니다. 더 알고 싶은 부분들은 생활코딩 강좌와 구글 검색 chat gpt와 함께 해결해나갔습니다.  1일차 - 섹션1 웹 개발 기본과 프로젝트 준비개발할 프로젝트에 대한 기능 설명과 웹의 동작 원리에 대해 배웠습니다.I. 웹 서비스 구성 요소1) 클라이언트요청 주체 2) 서버응답 주체서버간 통신에서는 서버가 요청 주체가 될 수도 있음  3) 데이터베이스데이터의 집합RDBMS를 의미하기도 함  II. 브라우저에서 주소창을 입력하면 일어나는 일1) 클라이언트 <-> DNS클라이언트가 DNS에 도메인을 보내면 DNS에서 도메인에 해당하는 IP 주소를 찾아서 알려준다. 2) 서버에 데이터 요청클라이언트가 전달된 IP 주소를 통해 서버에 작업을 요청하며 작업에 필요한 데이터를 함께 전달 3) 서버에서 작업 처리서버는 작업을 처리하며 일반적으로 데이터베이스에 대한 CRUD(삽입, 조회, 수정, 삭제) 등의 작업을 수행한다. 4) DB 결과 반환데이터베이스가 서버에서 요청한 결과를 반환한다. 삽입, 수정, 삭제의 경우 작업의 성공 여부를 응답하고 조회의 경우 조회도니 데이터를 전달한다. 5) 작업 결과 클라이언트에 전달서버가 반환된 결과를 클라이언트에 응답 한다.III. 웹 프레임워크와 Spring1) 웹 프레임워크동적 웹 서비스 개발을 편리하게 만들어주는 도구라이브러리와 다른 점은 제어의 주도권이 프레임워크에 있다. (라이브러리는 사용자가 주도권을 가짐)2) Spring Framework자바 기반의 웹 프레임워크웹 서버 개발을 모듈화 3) MVC 패턴 (Model-View-Controller)소프트웨어 아키텍처 디자인 패턴 중 하나데이터와 화면 전달 과정의 역할을 분담해 놓아 유지보수성을 높임  1) Model : 데이터 담기 2) View : 사용자에게 보내지는 화면 담당, 데이터 꺼내옴3) Controller : 요청 받아 작업 수행, Model에 데이터 넣음   4) 레이어드 아키텍처(Controller-Service-Repository)가장 대중적인 소프트웨어 아키텍처 기능별로 세가지 계층으로 구분됨Presentation(Controller)클라이언트가 요청할 수 있는 인터페이스를 정의 Business(Service)목적에 맞게 데이터를 처리 Data Access(Repository)데이터베이스에 접근하여 작업 요청, 다양한 데이터베이스 처리 방법을 제공하면 여러 서비스에서 공통적으로 사용할 수 있다.  5) 스프링 Bean과 의존성 주입(Dependency Injection)Bean : 스프링에서 관리되는 객체를 의미한다. 스프링 컨테이너가 주체가 되어 객체를 관리하는 것 이를 제어의 역전(Inversion of Control), IoC이라고 한다. 처음에는 상속과 동일한 것이라고 생각했는데 상속과는 분명한 차이점이 있었다.Chat Gpt 검색에 따르면 상속과 DI의 차이점은 의존성을 내부에서 관리하냐 외부에서 관리하냐에 따른 차이라고 한다.의존성 주입은 의존성을 외부에서 관리하므로 객체간 결합도를 낮추어 독립적으로 이용되어 코드를 유연하게 구성할 수 있는게 장점이라고 한다. 상속의 목적은 공통 기능을 공유하여 코드의 중복을 줄이는 것, 의존성 주입은 객체간의 결합도를 줄이고 코드 유연성을 높이는것에 초점이 맞춰져 있다. ex) Service와 Client 객체가 있을때 아래와 같이 외부에서 객체를 주입한다.val service = Service() val client = Client(service) client.doWork()  IV. HTTP와 REST API HTTP(Hyper Text Transfer Protocol)네트워크로 통신하는 두 컴포넌트 간의 통신 규약요청/응답1) RequestStartLine, Header, Body로 이루워짐Start Line : HTTP 메서드 , URL, HTTP 버전을 표시Header : 컨텐츠의 길이, 유형, 클라이언트 정보 표현Body : 서버에서 작업을 처리하기 위해 필요한 실질적인 데이터2) ResponseStartLine, Header, Body로 이루워짐Start Line : HTTP버전, 상태 코드, 메시지를 표현Header : 컨텐츠의 길이, 유형, 클라이언트 정보 표현Body : 응답 결과 데이터HTTP 요청 메서드Get, Post, Put, Patch, Delete각각 Read, Create, Update, Delete 작업을 요청할 때 사용c.f) Put과 Patch의 차이점 : Put은 리소스 전체를 새 데이터로 교체, Patch는 리소스의 일부만 수정HTTP 상태 코드요청의 처리 결과를 표현하는 코드 100 단위로 의미를 가지며, 상세한 코드로 구체적인 결과를 표현하기도 한다.200 : Ok300 : Multiple Choice400 : Bad Request500 : Internal Server Error Rest ApiHttp 통신으로 동작하는 어플리케이션 기능을 정의하는 컨벤션 강제성은 없음URL을 이용한 표현HTTP 메서드를 활용한 행위의 표현HATEOAS 준수복잡한 비스니스에서는 REST를 준수하기 어렵기 때문에 팀의 컨벤션을 만들어두는 것이 좋다. V. 데이터베이스의 정의데이터의 집합, DBMS관계형 DB, 비관계형 DB로 나누어짐관계형 DB는 표를 통해 데이터를 표현하며 각 표(테이블)은 관계를 가짐 비관계형 DB는 관계형 DB를 제외한 모든 DB (key-value형 등) VI. JPA(Java Persistence Api)자바 ORM 기술 표준 인터페이스1) ORM인스턴스와 관계형 데이터베이스를 매핑해주는 기술 2) 트랜잭션여러개의 DB 작업을 하나로 묶어주는 것 (두 작업이 모두 실패하거나 성공하도록 묶는 것)     2일차 - 섹션2 개발 - Domain흠... 기본 문법도 모르군객체 지향 프로그래밍도 알고 강의에서 어떤 역할을 하는 코드인지 계속해서 설명해주셔서 코드를 이해하는데 막히지는 않았습니다. 설명이 없는 개념은 대충 추론해가며 강의를 빠르게 들었습니다. 하지만 워밍업 클럽 미니 프로젝트를 위해서는 결국엔 기본 문법에 대해 어느 정도 알고 있어야 할것 같아 강의 코드를 중심으로 GPT와 유튜브 무료 코틀린 강의를 보면서 독학하는 시간을 길게 가져갔습니다. (Annotation과 Package에 관해서도 하나도 몰랐었을 정도로 무지했습니다...) 강의를 보고 따라한 후 Chat Gpt에 코드를 복붙 필요한 개념에 대한 간단한 설명과 함께 부탁했고이를 토대로 개념을 간단하게 학습한 후 추가적으로 궁금하거나 더 알아보고 싶은 부분을 적어 놓은 후 2일차 공부를 마무리 했습니다. 3~4일차 - 복습 및 과제강의를 빠르게 한 번 더 훝어본 후 2일차에 적어 놓은 부분을 구글 검색과 유튜브 등으로 해결 했습니다. 알바를 하면서 모르는 개념을 공부하고 과제도 하다 보니 시간이 촉박했지만 속도보다는 더 자세하게 이해하는게 더 중요하다고 생각해서 개념 공부에 시간을 많이 투자했습니다. 다행히 1주차에는 익숙한 깃에 대한 개념 강의가 섞여 있어서 좀 더 여유롭게 과제에 투자할 수 있는 시간이 있었습니다. 1주차 과제 - 프로젝트 ERD 작성음 분명 강의 들었을땐 이해됬었는데강의에서 사용한 포트폴리오 사이트에 대한 테이블 설계에 대해서는 이해가 정말 잘 되었습니다. 하지만 제 프로젝트에서는 테이블을 어떻게 나눠야 할지 아직 이해가 부족했습니다.추가로 생활코딩님 유튜브를 보면서 공부한 후 다시 강의를 들으니 이해가 훨씬 수월 했습니다. 혹시 저처럼 테이블 설계에서 어려움을 느꼈던 분들은 보시면 도움이 될거 같습니다.https://www.youtube.com/watch?v=1d38YZKCM88&list=PLuHgQVnccGMDF6rHsY9qMuJMd295Yk4sa 처음에는 ERD를 나눌 때 HTML, CSS 작성할때처럼 종속관계가 있어야 좋다고 생각했었지만 강의를 듣고나서는 유지 보수와 확장을 고려해 서로 간의 의존도를 줄이는게 중요하다는걸 알았습니다. 최종적으로 작성된 ERD입니다. 전체 구성사용자 -> 목표로 선택된 책 -> 도서별 세부 목표 -> 목표마다 달린 댓글 구조로 설계했습니다. 사용자 -> 목표로 선택된 책1:N 관계입니다 한명의 사용자가 여러개의 책을 선택할 수 있기 때문에 이렇게 설계했습니다. 처음에는 웹에 있는 도서 목록을 크롤링해서 DB에 넣은 다음 도서 선택을 하는 식으로 할까 고민했었는데 크롤링할 양도 많고 DB에 없는 책을 목표로 선정하고 싶은 경우가 생길 것 같아서 그냥 사용자가 직접 목표 책에 대해 작성할 수 있도록 설계하기로 했습니다. (추후에 서비스를 좀 더 확장하게 된다면 Yes24나 교보문고 같은 사이트에 연결하며 광고 등을 붙이는 구성을 생각하고 있습니다. 만약 그렇게 된다면 유저가 직접 작성한 책과 연동된 책을 따로 다른 테이블에 두어 작성하는것이 기존 DB를 수정하지 않아도 되서 더 좋을거 같다고 생각합니다.) 등록된 책 -> ChosenBook1:N 관계입니다. 등록된 책을 다른 여러 사람들이 선택해서 사용할 수 있기에 이렇게 작성했습니다.  책을 처음 등록하면 DB에 저장하고 다른 사람들이 같은 책을 목표로 삼을때 사용할 수 있도록 지정하면 DB 부담이 좀 줄어들거 같다고 생각해서 이렇게 설계했습니다. 목표로 선택된 책 -> 세부 목표1:N 관계입니다. 하나의 책의 여러개의 세부 목표를 둘 수 있기에 이렇게 설계했습니다.  user에 바로 연결할지 아니면 책과 연동해서 작성해야 할지 고민했는데 사용자별 목표를 보여주는 것보다는 도서별 목표로 보여주는 것이 좀 더 독서 습관 만들기라는 취지에 더 어울릴 것 같아 이렇게 설계했습니다. 세부 목표 -> 댓글1:N 관계입니다. 목표별로 다른 사용자들이 여러 댓글을 달 수 있기에 이렇게 설계하였습니다.   5일차 - 최종 점검최종 점검 이라 적었지만 거의 대부분은 다른 분들이 올리신 과제를 확인하면서 제 과제에 잘못된 부분은 없는지 확인하는 시간이였습니다. 아직 ERD에 대한 확신이 없어서 과제를 올린 후에도 여러번 고쳤던것 같습니다.https://github.com/dellyu03/bookjeogX2ㄴ 혹시 ERD나 프로젝트에 대해 지적해주실 분 있으시면 언제든 환영입니다.   1주차 회고군대를 전역하고 나서 새로 시작한 알바와 워밍업 클럽 과정을 병행해나간 바쁜 한 주였습니다. 휴학하면서 혼자서 공부할 때면 집중하기도 어렵고 딴 짓 하기 바빴는데 정확한 목표를 설정해 주시고 과제도 내주시니 집중이 더 잘되었습니다. 혼자서 그냥 설렁설렁 한달 공부했던 효과를 1주일 압축으로 해낸 것처럼 배운것도 정말 많았습니다. 앞으로도 이렇게 천천히 노력해가면서 꼭 완주를 해내겠다는 다짐을 하게된 한 주였습니다. 

백엔드워밍업클럽스터디기록백엔드코틀린스프링부트

javajava

인프런 워밍업 클럽 2기 - 백엔드 클린코드, 테스트코드 1주차 발자국

1주차 발자국 미션 정리 강의 출처 - Readable Code: 읽기 좋은 코드(인프런, 박우빈) (https://www.inflearn.com/course/readable-code-%EC%9D%BD%EA%B8%B0%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%82%AC%EA%B3%A0%EB%B2%95) - 한 주간 배운 것들1) 추상: 추상이란 어떤 것의 중요한 점만 뽑아 추려내는 것. 코드에서도 추상화를 통해 중요한 점 만을 뽑아내어, 가독성을 향상시킬 수 있다. 강의를 듣기 전에는 추상화란 개념에 대해 뜬구름처럼 들렸는데, 메소드 레벨에서의 추상화, 추상화의 예시 등 강의를 들으니 더 구체적으로 이해할 수 있었다. 또한 예시 코드를 리팩토링하면서 코드 간 추상화레벨을 맞추면서 네이밍하거나 메소드를 추출하는 등의 습관이 코드 가독성에 중요하다는 것을 알 수 있었다. 2) 뇌 메모리 적게 쓰기: 개발자는 코드를 작성하다보면 여러가지 정보들을 생각하면서 코드를 짜야한다. 계속 생각해야 하는 정보들을 가능한 줄이면 줄일수록 코드를 작성할 때나, 읽을 때나 나아진다. 예를 들면return문을 활용하여 불필요한 조건문을 줄이거나, 될 수 있으면 부정어를 사용하지 않는 등의 습관을 들이는 것이 좋다. 이 부분은 기존에도 노력하고 있던 부분이라 리마인드해서 좋았다. 3) 객체지향과 추상화: 객체지향의 5대원칙이라고 불리는 SOLID에 대해 정리할 수 있었다. 객체, 객체의 협력과 책임, 관심사의 분리와 같은 개념을 정리했다. 또한 기존 코드를 리팩토링 하면서, 높은 응집도와 낮은 결합도를 어떻게 구현할 수 있는지 SOLID원칙과 함께 눈으로 확인할 수 있어서 좋았다. 4) 객체지향의 적용: 객체지향 원칙을 지키기 위한 코드레벨에서의 방법에 대해 공부했다. 예를 들면 상속과 조합, 값 객체(Value Object), 일급 컬렉션, Enum과 다형성을 활용한 코드 리팩토링을 진행했다. 공부한 이론을 코드에서 바로 적용시켜볼 수 있는 점이 좋았던 것 같다. - 미션 해결 과정1) day2 미션: 강의 내용에서의 추상과 구체에 대한 나만의 예시를 생각하는 미션이었다. 강의 내용대로, 구체를 잘 나타내는 추상과 추상을 잘 나타내는 구체를 찾기 위한 적절한 예시가 실생활에서 있는지 고민해봤다. 강의를 들을 때 미열이 나는 상태여서, 나는 '몸에서 열이 난다'라는 추상을 인터넷 기사를 서칭하여 구체로 풀어냈다. 2) day4 미션: 추상화가 덜 되어있는 코드를 강의에서 배운 내용대로 리팩토링하는 미션이었다. 해당 코드를 보자마자 든 생각은 읽기 어렵다 라는 생각이었다. 불필요한 조건문이 보였고, return문을 활용하면 하나하나 쪼갤 수 있을 것 같았다. 또한 객체에 getter를 사용하여 직접 접근을 해서 데이터를 가져오고 있었기에 이 또한 해당 객체에 역할을 위임할 수 있을 것 같았다. 그리고 마지막엔 적절하게 추상화 레벨을 나눠서 private 메소드를 만들어줬다. - 회고1) 강의 수강: 생각보다 시간이 오래걸렸다. 하루에 2~3시간 분량의 진도표를 따라갔는데, 학교수업과 병행하자니 시간 분배가 어려웠다. 그래서 남는 시간마다 강의를 수강했는데, 띄엄띄엄 수강하다보니 집중이 덜 되었던 것 같다. 이 부분은 새로 시작하는 2주차부터 시간을 잘 분배해서 활용해야겠다는 생각이 든다. 2) 미션: 미션 해결 과정이 어려운 편은 아니었으나, 커뮤니티에 올라온 다른 분들의 글을 참고하니 같은 미션이라도 이런 식으로 접근할 수 있구나 하고 생각할 수 있었던 점이 좋았다.

백엔드

임원기

인프런 워밍업 스터디 클럽 2기 - 백엔드(클린코드, 테스트코드) 1주차 발자국

클린 코드를 추구하는 이유는?개발을 시작한지 좀 된 사람이라면 로버트 마틴의 ‘클린 코드’라는 책을 읽진 않아도 들어 봤을 것이다.클린 코드의 부제를 보면 '애자일 소프트웨어 장인 정신'인데 부제 그대로 장인 정신에 관한 내용이다. 여기서 거추장스럽게 애자일이 뭔지 이해할 필요 없이 클린 코드의 목적을 말하자면 바로 '가독성'을 추구하는 것이다.코드는 사람이 작성하고, 읽기 때문에 클린 코드를 추구해야하는 근원적 이유는 눈에 잘 들어오고 쉽게 이해가능 해야하는 것이다.하지만 이를 왜 지켜야할까? 그 이유를 코드를 통해 체득해 나가는 것이 이 강의의 핵심 주제이다. 추상이를 체득하기 위해 가장 중요한 키워드는 바로 '추상'인데 강의 내내 보게 될 키워드이며 그만큼 중요하다.추상의 사전적 의미 다음과 같다.여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용.사물이나 개념에서 특성이나 속성을 추출한다고 나와있다. 개발이 아니더라도 일상 생활에서 '추상적 사고'는 이미 뿌리깊이 자리 잡고 있다.예를 들어 '날씨'는 대기 중에서 일어나는 모든 기상 현상을 포괄하는 추상적 개념으로 온도, 습도, 강수량, 기압 등의 요소가 결합하여 특정한 기후 조건을 형성하는 것을 의미한다.이를 구체적으로 바라본다면 “오늘 아침 기온은 20°C이고, 바람은 시속 10km로 불고 있으며, 30%의 습도를 동반한 맑은 하늘”이라는 식으로 각 요소를 수치로 구체화할 수 있다. (미션-Day2)정리하면 '구체'라는 것은 여러가지 개별 사건에 하나하나 대응하는 것으로, '추상'은 공통적인 특징을 하나로 정리해 일반화한 것이다.이처럼 적절한 추상화는 일상 생활 뿐만 아니라 컴퓨터 과학에서 다루는 복잡한 데이터를 읽기 쉽게 도와준다.클린 코드는 이를 다음과 같이 설명한다. 우리가 함수를 만드는 이유는 큰 개념을(다시 말해, 함수 이름을) 다음 추상화 수준에서 여러 단계로 수행하기 위해서가 아니던가. - 클린코드, 45page사실 이미 클린 코드에 나온 내용을 강박처럼 지키고 있었기 때문에, 섹션 2인 추상과 섹션 3 논리, 사고의 흐름은 어려움없이 넘길 수 있었다.때문에 Day4 미션인 읽기 좋은 코드로 리팩토링하기도 어려움없이 코드를 작성할 수 있었다. // 리팩토링 전 public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; } // 리팩토링 후 public boolean validateOrder(Order order) { try { validateItems(order); validateTotalPrice(order); validateCustomerInfo(order); } catch (InvalidOrderException e) { log.info(e.getMessage()); return false; } return true; } private void validateItems(Order order) throws InvalidOrderException { if (order.hasNoItems()) { throw new InvalidOrderException("주문 항목이 없습니다."); } } private void validateTotalPrice(Order order) throws InvalidOrderException { if (order.isPricePositive()) { throw new InvalidOrderException("올바르지 않은 총 가격입니다."); } } private void validateCustomerInfo(Order order) throws InvalidOrderException { if (order.hasNoCustomerInfo()) { throw new InvalidOrderException("사용자 정보가 없습니다."); } } // 커스텀 예외 InvalidOrderException class InvalidOrderException extends Exception { public InvalidOrderException(String message) { super(message); } } 조기 Return, 부정어로 인한 읽는데 중간에 한번 막히게 되는 코드 개선, 예외 처리 등 한 눈에 코드를 알아볼 수 있게 끔 리팩토링 해봤다. 이 부분은 코드가 더 복잡해진다면 어떻게 하면 좋을지 숙련이 필요하다고 생각하게 된 부분이었다. 전체적으로 규칙뿐만 아니라 추상화라는 거대한 개념을 이해하기에 아주 좋은 파트였다.객체 지향 적용하기객체 지향 패러다임, 특히나 객체 지향 5원칙인 SOLID는 기계처럼 법칙을 외운다고 해서 절대 이해할 수 없기 때문에 이해한 것을 바탕으로 코드를 재구성해봤다. - 미션 Day4코드를 쓰면서 계속 염두에 뒀던 것은 비즈니스 요구 사항이 항상 변경될 것을 인식하고 있었다는 것이다. 나중에 요구 사항이 바뀌더라도 작성했던 코드의 틀을 유지하면서 변경하려면 어떻게 해야할까?라는 고민을 자연스럽게 하게되었다.그에 대한 키워드는? 역시나 '추상화'였다.미션에서 작성했던 코드와 글의 마무리가 만족스럽지 않아, 다시 SOLID 원칙을 다시 짧게 정리해본다면> SRP: 모듈(클래스 or 클래스의 집합)이 변경되는 이유는 한 가지여야 함 -> 책임에 따라 코드를 분리하게되면 새로운 비즈니스 요구 사항이 생겼을 때 변화가 발생하더라도 수정할 대상이 명확해진다.> OCP: 확장에 대해 열려있고 수정에 대해 닫혀있다는 것 -> 인터페이스에 의존하도록 추상화함으로써 기존 코드를 수정하지 않은 채 수정 및 확장이 가능> LSP: 하위 타입은 상위 타입을 대체할 수 있다는 것 -> upcasting된 상태에서 부모의 메서드를 사용해도 동작이 의도대로 흘러가야 함> ISP: 클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 함 -> 목적과 용도에 적합한 인터페이스 만을 제공하는 것이 목표> DIP: 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 되며, 저수준 모듈이 고수준 모듈에 의존해야 함 -> 추상 클래스나 인터페이스를 참조하여 거의 변화가 없는 것에 의존시켜 각 클래스간의 결합도를 낮추는 것이 목적이렇게 정의할 수 있지 않을까 싶다.이제 컴포지션 사용, VO 객체, 일급 컬렉션과 같은 개념들은 이어지는 미션에서 직접 적용하고 글을 다시 정리해 볼 생각이다.맺음강의를 보며 단순히 ‘깨끗한 코드’라는 차원을 넘어서, 내가 작성한 코드를 나중에 동료들이 쉽게 이해할 수 있을까에 대한 고민을 계속 하게되는 시간을 보냈다.그러던 중, 인프콘에서 발표를 마치고 토비님이 블로그에 남기신 말이 있는데클린 코드는 그저 이름 잘 짓고, 함수 작게 만들고, 주석 달지말고, 스타일 통일하고, 디미터 법칙 지키자라는 수준의 피상적이고 기계적인 주장을 하는 캐치프레이즈가 아니다. 대부분 앞부분만 보고 6장 넘어서 나오는 내용에 대해서는 얘기도 하지 않는, 책에 나오는 저자가 꽤나 고민하면서 수집하고 애써 만진 코드는 술렁술렁 넘기고 말 책이 아니란 말이다.읽으면서 굉장히 따끔한 문장이었다. 클린 코드는 단순히 형식적인 규칙을 따르는 것이 아니라, 코드를 읽는 사람, 즉 나와 동료 개발자들 간의 소통을 원활하게 하고, 더 나아가 유지보수성과 확장성을 높이는 데 중점을 둬야한다는 것이다.더 이상 코드를 ‘깨끗하게’만 작성하는 것이 목표가 아니라, 의도를 명확히 전달하고, 미래의 변화에 유연하게 대응할 수 있는 코드를 작성하는 것이 중요하다는 점을 깨달았다. 앞으로도 클린 코드 원칙을 단순한 규칙 그 이상으로 생각하며, 더 나은 개발자, 더 나은 동료가 되기 위해 지속적으로 고민하고 실천하도록 노력해야겠다.출처- Clean Code- 우빈님의 강의- 애자일 소프트웨어 개발 선언- 토비님의 블로그 

ailen22

[인프런 워밍업 클럽 2기 - 백엔드 프로젝트(Kotlin, Spring)] 1주차 발자국

1주차 발자국  웹 개발 기본 개념프레임워크와 라이브러리웹 프레임워크프레임워크가 주도권을 가지고 있음동적 웹 서비스 개발을 편리하게 만들어주는 도구웹을 개발할 때 공통적으로 요구되는 기능들을 보다 편리하게 사용할 수 있도록 함라이브러리사용자가 주도권을 가지고 원하는 것을 만들 수 있음  프로젝트 환경구성DependenciesSpring Web : Spring MVC를 사용하여 RESTful을 포함한 웹을 구축Spring Data JPA: Spring Data 및 Hibernate를 사용하여 Java Persistence API로 SQL 저장소의 데이터를 유지H2 Database: 작은(2MB) 설치 공간으로 임베디드 및 서버 모드와 브라우저 기반 콘솔 응용 프로그램을 지원MySQL Driver: MySQL JDBC 드라이버Thymeleaf: HTML을 브라우저 및 정적 프로토타입으로 올바르게 표시Validation: Hibernate 유효성 검사기를 사용한 Bean 유효성 검사(Spring Security)  어노테이션 정리Id : 테이블의 기본 키(PK)에 대응함을 선언 Entity : JPA 엔티티임을 선언GeneratedValue : @Id의 생성 전략을 선언GenerationType.IDENTITY : PK 생성을 DBMS에 위임(MySQL에서는 auto_increment를 사용)GenerationType.TABLE : PK 생성 전용 테이블을 사용GenerationType.SEQUENCE : DBMS의 시퀀스 오브젝트를 사용하여 PK를 생성GenerationType.AUTO : JPA의 알고리즘에 따라 DBMS에 적합한 전략을 선택Column : 필드가 컬럼명이 기본 전략에 의해 변환된 값과 다 르거나 구체적인 속성을 따로 정의해주기 위해 사용MappedSupperClass : 여러 엔티티의 공통 컬럼을 갖고 있는 상위 클래스에 사용CreatedDate : 생성된 시간을 자동으로 저장LastModifiedDate : 수정된 시간을 자동으로 저장Enumerated : Enum 타입의 필드를 데이터베이스 컬럼과 매핑할 때 사용EnumType.ORDINAL : Enum 내부에 정의된 순서대로 번호를 지정해 값을 저장EnumType.STRING : Enum의 이름을 값으로 사용Columnnullable : 해당 컬럼이 null일 수 있는지 정의updatable : 해당 컬럼의 값이 변경될 수 있는지 정의OneToMany : 한 엔티티가 여러 다른 엔티티와 관계를 맺는 경우ManyToOne : 여러 엔티티가 한 엔티티와 관계를 맺는 경우  미션[미션1]테이블설계, [미션2] 깃허브 리포지토리에 프로젝트 올리기깃허브 리포지토리에 프로젝트 올리는 것은 문제가 없었으나 테이블 설계를 하면서 신경쓸 부분이 많아서 제출을 급하게 하게된 것이 아쉬웠다.다시 생각해보고 구상해서 테이블을 설계해야 할 것 같다. 그리고 ReadMe 파일도 제출 기한에 쫓겨 급박하게 작성해서 제출하느라 아쉬운 점이 많았다. 다시 보기 깔끔하게 올려야할 것 같다. https://github.com/lee-soohyun/StudentManagement

성규

[워밍업 클럽 스터디 2기 :: BE 클린코드 & 테스트] 1주차 발자국

 뇌 메모리 적게 쓰기프로그램 = 데이터 + 코드정리하는 뇌정리 시스템에서 중요한 과제는 최소의 인지적 노력으로 최대의 정보를 제공하는 것이다.도둑맞은 집중력뇌는 한 번에 한 가지 일 밖에 하지 못한다.인지적 경제성을 추가하자Early returnEarly return 으로 else의 사용을 지양하자Early return 을 통해서 끊어서 볼 수 있도록 하여 이후 불필요한 로직을 수행하지 않도록 처리사고의 depth 줄이기중첩 분기분, 중첩 반복문‘무조건 1 depth로 만들어라’ 가 아니다. → 보이는 depth를 줄이는 데에 급급한 것이 아니라, 추상화를 통한 사고 과정의 depth를 줄이는 것이 중요 → 2중 중첩 구조로 표현하는 것이 사고하는 데에 더 도움이 된다고 판단한다면, 메서드 분리보다 그대로 놔두는 것이 더 나은 선택일 수 있다. 때로는 메서드를 분리하는 것이 더 혼선을 줄 수도 있다.무조건 strame 이 인지하기 좋은 것은 아니다. for i, foreach 가 더 좋은 경우도 있으니 상황에 맞게 사용하자사용할 변수는 가깝게 선언하기Beforeint i = 10; // 코드 20줄..... int j = i + 10; After// 코드 20줄..... int i = 10; int j = i + 10; 파라미터를 줄일 수 있다면 줄이는게 좋다.공백 라인을 대하는 자세공백 라인도 의미를 가진다. → 복잡한 로직의 의미 단위를 나우어 보여줌으로써 읽는 사람에게 추가적인 정보를 전달할 수 있다.부정어를 대하는 자세부정어구를 쓰지 않아도 되는 상황인지 체크부정의 의미를 담은 다른 단어가 존재하는지 고민 or 부정어구로 메서드명 구성※ 부정 연산자(!)의 가동성 ↓if(!isLeftDirection()){ } // 반대대는 상황이 있다면 if(!isRightirection()){ } // 메서드명에 Not 을 추가하는 방법 if(isNotLeftDirection()){ } 해피 케이스와 예외 처리사람은 해피 케이스에 몰두하는 경향이 있다.예외가 발생할 가능성 낮추기어떤 값의 검증이 필요한 부분은 주로 외부 세계와의 접점의도한 예외와 예상하지 못한 예외를 구분하기Null을 대하는 자세항상 NullPointException을 방지하는 방향으로 경각심 가지기메서드 설계 시 return null을 자제한다. → 만약 어렵다면, Optional 사용을 고민해 본다.Optional에 관해Optional은 비싼 객체다. 꼭 필요한 상황에서 반환 타입에 사용한다.Optional을 파라미터로 받지 않도록 한다. 분기 케이스가 3개나 된다. (Optional이 가진 데이터가 null인지 아닌지 + Optional 그 자체가 null인지)Optional을 반환받았다면 최대한 빠르게 해소한다.잘못 사용된 Optional은 안티패턴이다. (JPA에서의 Optional 은 잘 사용된 패턴)Optional을 해소하는 방법분기문을 만드는 isPresent()-get() 대신 풍부한 API 사용orElse(), orElseGet(), orElseThrow()의 차이 숙지orElseThrow() : 그냥 쓰면 됨orElse() : 항상 실행, 괄호안의 값이 확정된 값일때 활용orElseGet() : null인 경우 실행, 값을 제공하는 동작(Supplier) 저의public T orElse(T other){ return value != null ? value : other; } Intger result = somethingOptional.orElse(methodHeavy()); // 호출할 필요가 없는 경우에도 항상 실행 Intger result3 = somethingOptional.orElse(0); // 정해진 값일 때 사 public T orElseGet(Supplier<? extends T> supplier){ return value != null ? value : supplier.get(); } integer result = somethingOptional.orElseGet(() -> methodHeavy()); // null인 경우에만 실행 예외를 던지고 그 안에 메세지를 넣어서 무슨 오류인지 인지할 수 있게 도와주자비교를 할 때 상수와 변수를 비교해야 한다면 상수를 앞에 넣어서 NullPointException 이 안 일어나게 할 수도 있다추상의 관점으로 바라보는 객체 지향객체 : 추상화된 데이터 + 코드관심사의 분리유지 보수가 원활해진다.높은 응집도, 낮은 결합도객체 설계하기객체 : 데이터 + 코드객체(Object)로 추상화 하기비공개 필드(데이터), 비공개 로직(코드, 기능 구현부)공개 메서드 선언부를 통해 외부 세계와 소통 → 각 메서드의 기능은 객체의 책임을 드러내는 창구객체의 책임이 나뉨에 따라 객체 간의 협력이 발생객체가 제공하는 것절차 지향에서 잘 보이지 않았던 개념을 가시화관심사가 한 군데로 모이기 때문에, 유지보수성 ↑ → ex) 객체 내부에서 객체가 가진 데이터의 유효성 검증 책임을 가질 수 있다.여러 객체를 사용하는 입장에서는 구체적인 구현에 신경 쓰지 않고 보다 높은 추상화레벨에서 도메인 로직을 다룰 수 있다.새로운 객체를 만들때 주의할 점1개의 관심사로 명확하게 책임이 정의되었는지 확인하기 → 메서드를 추상화 할 때와 비슷하다. → 객체를 만듦으로써 외부 세계와 어떤 소통을 하려고 하는지 생각해보자.생성자, 정적 팩토리 메서드에서 유효성 검증이 가능하다. → 도메인에 특화된 검증 로직이 들어갈 수 있다.Setter 사용 자제→ 데이터는 불변이 최고다. 변하는 데이터라도 객체가 핸들링 할 수 있어야 한다.→ 객체 내부에서 외부 세계의 개입 없이 자체적인 변경/가공으로 처리할 수 있는지를 확인→ 만약 외부에서 가지고 있는 데이터로 변경 요청을 해야하는 경우, ‘set~’이라는 단순한 이름 보다는 ‘update~’ 같이 의도를 드러내는 네이밍을 고려하자.Getter도 처음에는 사용 자제. 반드시 필요한 경우에 추가하기→ 외부에서 객체 내 데이터가 필요하다고 getter를 남발하는 것은 무례한 행동이다.객체에 메시지를 보내라단일 책임의 원칙 :SRP : Single Responsibility Principle하나의 객체는 각자 맞는 책임을 가지게OCP : Open-Closed Principle추상화와 다형성을 이용!객체 자체는 무엇이 들어와도 처리가능 하게인터페이스를 통해 다양한 값이 들어 올 수 있도록 처리LSP : Liskov Subsitution Principle부모에서의 기능을 자식에서도 동일하게ISP : Interface Segregation Principle클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안된다. → 인터페이스를 잘게 쪼개라ISP를 위반하면, 불필요한 의존성으로 인해 결합도가 높아지고, 특정 기능의 변경이 여러 클래스에 영향을 미칠 수 있다.※ 기능단위로 인터페이스를 작게 사용해라! DIP : Dependency Inversion Principle의존성 : 하나의 모듈이 다른 하나의 모듈을 생성하거나 사용하는 모든 것, 참조하는 것의존성 순방향 : 고수준 모듈이 저수준 모듈을 참조

백엔드

이예진

인프런 워밍업 클럽 Backend - 1주차

~ 이번주 요약 ~웹이 운영되는 구조, 웹프레임워크와 spring, HTTP와 API, 데이터베이스 구조, JPA, ORM 등 백엔드에 필요한 기초 내용 학습 ~ 추가로 더 학습하고 익혀야 할 것들 ~스프링 Bean - 스프링에서 관리되는 객체, 자바 클래스의 인스턴스. 스프링 컨테이너가 주체가 됨. (제어의 역전, IoC)의존성 주입 - Bean에서 다른 Bean을 사용할 경우(의존하는 경우), 스프링 컨테이너에서 의존성을 주입해줌. 한 객체가 사용하는 다른 객체를 객체 내부에서 직접 만들지 않고, 외부에서 주입받아서 사용하는 방법. (약간 상속 같은 느낌)스프링이 실행 될 때 컴포넌트 스캔과정을 걸쳐 Beam으로 지정된 클래스들의 객체를 모두 만들어둠. 의존성을 주입 받는 방법은 3가지가 잇는데, 생성자 주입 방식을 권장.관계형 데이터베이스의 구조 (1:N이란 무엇인가- 하나가 여러개의 데베속성? 종류? 를 가질 수 있다는 소리같은데 맞나... , N:M은 무엇이고 어떻게 만드는가)JPA - 자바의 객체를 관계형 DB의 테이블로, 그 반대로 변환 해주는 기능을 하는 맵핑을 해주는 라이브러리ORM - 객체 관계 매핑, 객체지향 프로그래밍의인스턴스와 관계형 뎅터베이스를 매핑 해주는 기술, 각 테이블들이 갖는 관계까지 이용하여 DB를 좀 더 쉽게 다룰 수 있도록 기능 제공코틀린 코드 (작성한 것과 주석, 필기로 다시 어떤 코드가 무슨기능을 하는지 익힐 필요가 있음...) => 코드가 흘러가는 전체적 흐름을 파악하여 각각의 코드가 무슨 기능을 하고, 기초 명령어를 알아야 두어야 할 것 같다...다음주에 이번에 알듯말듯한게 확실히 잡혔으면 좋겠지만 그렇지 않다면... 주말에 시간을 추가적으로 내야할 것 같다...   ~ 미션 ~한 명의 유저는 여러개의 캐릭터를 가질 수 있다. (-> 매칭 테이블을 따로 만들어 두었다)한 명의 유저는 캐릭터를 가질 수도 있고, 안 가질 수도 있다.하나의 캐릭터는 여러개의 키워드를 가질 수 있다. (-> 매칭 테이블을 따로 만들어 두었다)하나의 캐릭터는 키워드를 가질 수도 있고, 안 가질 수도 있다.여러 캐릭터가 똑같은 키워드를 가질 수 있다. (-> 따라서 하나의 테이블로 만들어 두었다)처음에는 유저id와 캐릭터 id로 매칭하여 PK를 하려했으나, 최소성에 어긋나기도 하고, 하나의 칼럼을 늘려도 데이터베이스의 크기에 큰 영향을 줄 것 같지않아, 두 테이블을 매칭시키는 테이블(My Character, Character Keyword)에 따로 각각 PK를 설정해두었다.                  

인프런 스터디 1주차 백엔드 클린 코드, 테스트 코드 스터디 발자국

학습한 내용섹션2섹션2의 가장 중요한 부분은 추상화가 아니였을까 싶다. 막연하게 추상화를 해야좋다 해야좋다라고만 생각했는데, 강사님께서 강의하면서 알려주신 '상세한 구현부가 나오는게 추상화 레벨이 맞지 않다.' 이 부분이 와닿았다. 섹션3클린코드에서 다루는 몇가지 준수하면 좋을만한 사항에 대해서 학습하였다.섹션4 섹션4에서는 조금은 이론적인 부분에 대해서 학습했다. SOLID 그냥 이론만 알았지, 실제로 어떻게 적용할지는 막막하긴했다. SRP는 항상 어려운것 같고.. SOLID와 객체지향 패러다임에 대해서 학습하였다.섹션5섹션5에서는 좀 더 실전편(?) 같은 느낌이다. 어떻게 하면 SOLID원칙 말고도 더 객체지향적으로 다가갈 수 있을까에 대해서 나온다. 가장 도움이 된 파트가아닐까 생각한다. 회고는 4Ls에 맞춰서 작성하려고 한다.Liked (좋았던 점)평소에 관심을 가지고 있었던, 막연하게 이론만 알고 어떻게 해야할지 잘 와닿지 않았기 때문에 강의를 수강하려고 했었는데, 마침 좋은 기회가 되어서 스터디를 병행하면서 하게 되었다. 일단 스케쥴이 빡빡하긴 하지만, 그래도 내가 관심을 가지고 있던 부분이기 때문에 즐겁게 들을 수 있었다.Lacked (아쉬웠던 점)일정이 너무 빡빡하다.. 이 강의만 듣는게 아닌 다른 일정들이 있기 때문에 최소 하루에 2시간을 투자해야하는 강의를 쉽게 익히기가 쉽지 않았다. 그래서 최대한 주말이나, 쉬는날에 많이 들으려고 노력은 했지만 강의를 내걸로 만들지 못하고 있는 느낌이 드는게 아쉽다. 추후에 다시 한번 복습하는 과정이 필요할 것 같다.Learned (배운 점)추상화 레벨을 맞춰라, 그리고 SOLID원칙에 대해서 다시한번 생각해보게 되었다. 그냥 너무 막연하게 코드를 짜고있었다. 나름 클린코드를 지향하며 작성한다고 생각했었지만, 항상 어디까지 분리를 하는게 좋고, 어떻게 짜는게 더 좋을지 고민이 많았다. '추상화 레벨을 맞춰라'라는 이야기가 많이 공감이 되었다. 읽으면서 잘 추상화되어있는 메서드들을 읽다가 갑자기 상세한 구현부가 나오면 당황한다. 이것을 생각하면서 나도 추상화 레벨을 맞추려고 노력하고 있다. 그리고 SOLID원칙은 항상 글로만 접했지 실제로 적용되는게 크게 와닿지 않았는데, 적절한 상황에 맞춰서 알려주셨기 때문에 다시한번 이해가 안갈대 꺼내보면 좋을 것 같다.그리고 getter를 지양하자는 것도 나는 계속 하나씩 만들어내는것보다 복잡한 상황에 getter를 쓰는게 더 나을수도 있다고 생각했는데 그런 생각도 조금 바뀌었다. 사소한거 하나라도 getter를 사용하기보단, 좀 더 의미있는 이름으로, 그리고 구현부를 가릴 수 있도록 노력해야겠다고 생각했다. 하드웨어의 성능이 좋아졌기 때문에 코드의 중복을 줄이는 것은 그렇게 큰 의미가 있지는 않다는 말도 참 와닿았다.Longed for (앞으로 바라는 점)내가 좀 더 노력해서 강의를 더 집중해서 들어야겠다고 생각한다. 그리고 바쁜 이유도 다른 일정이 있기 때문도 있지만, 프로젝트에 내가 배운 내용들을 적용해 볼 수 있다는 부분은 참 다행이라고 생각한다.강의를 그냥 보기만 하고 예제코드를 따라 치는데 그치지않고, 내가 지금 짜고 있는 코드들에 강의에서 배운 개념을 접목시켜서 쓰도록 더 노력해야겠다. 코드를 계속짜면서 강사님이 해주신 말들을 되뇌이면서 코드를 작성하도록 하자

인프런 워밍업 클럽 1주차 발자국

 1주차 강의 정리추상과 구체이름 짓기에서 중요한점메소드의 추상화메소드 시그니처에 의미를 담는 것동일한 추상화 레벨매직 넘버 & 매직 스트링"정리 시스템에서 중요한 과제는 최소의 인지적 노력으로 최대의 정보를 제공하는 것이다." <대니얼 J.래비틴, 정리하는 뇌>early return -> if else의미있는 단위로 depth 줄이기의미있는 공백 라인부정어 사용 지양예외 처리 & 예상 가능한 예외 및 예상 불가능한 예외객체의 설계SOLID 1주차 강의 회고좋았던 점강의 내용이 매우 유익했다.이전 프로젝트에서 놓치고 있었던 점을 다시 되돌아 볼 수 있는 기회가 되었다.코드 작성시 사고의 관점을 어떻게 해야하는가를 생각해볼 수 있었다.아쉬웠던 점스스로 계획한 일정을 지키지 못했다.배운 점설계 관점에서 필요한 부분과 코드 작성시 유의할 점 등을 새롭게 알게 되었다.프로젝트에 객체지향 설계를 적용해보면서 SOLID의 개념을 알 수 있었다.앞으로 바라는 점계획한 일정을 지키는 것.기록을 꼼꼼하게 하는 것. 미션Day 2-> 추상과 구체의 예시를 잘 설명할 수 있는 소재에 대한 고민을 했다.-> '우린다'라는 추상 안에 일어나는 자세한 과정을 구체로 표현할 수 있다고 생각. 추상: 차를 우린다.구체티백이 담긴 컵에 적절한 온도의 물을 붓는다.티백 표면으로 물이 들어가 찻잎과 접촉한다.찻잎의 성분이 물에 용해된다.용해된 찻물은 농도가 높은 티백쪽에서 농도가 낮은 물쪽으로 확산된다.  Day4-> SOLID의 개념을 내가 이해한 문장들로 표현하고자 했다.-> 리팩토링 과제는 다음을 중점점으로 생각하였다.1. Early return 활용2. 부정어 사용 지양3. 의미있는 메소드 이름 짓기4. 사고의 depth를 줄이기5. 예외 처리https://lapis-dew-01f.notion.site/Day4-1147d24093d6807a86bed3f901a3322a?pvs=4 orElse() vs orElseGet() orElse()과 orElseGet()의 인자로 들어가는 값이 부하가 크다면 orElse()는 성능 문제를 일으킬 가능성이 있다.orElse()의 내부 구현은 다음과 같다.public T orElse(T other) { return value != null ? value : other; }other 값을 반환하기 위해 other 값을 항상 평가하게 된다. 내부에서 다루는 값이 평가된 값이라는 것. 예외처리 시 항상 throws를 사용해야하는가?

Ohss

[인프런 워밍업 클럽 백엔드 스터디 2기] 1주차 발자국

1주차 학습 내용클린 코드가 필요한 이유미래의 나 혹은 다른 사람이 코드를 읽는 데 소요되는 시간과 자원이 절약된다. = 유지보수가 용이하다. [Section2] 추상클린 코드를 위한 핵심 주제구체적인 정보들에서 핵심만 추려 표현복잡한 로직을 단순하게 표현 -> 읽기가 좋다적절한 추상화를 위한 변수 및 메서드의 naming, 상수화, 추상화 레벨을 동등하게 맞춰 읽기 좋은 코드를 작성하는 법에 대해 학습  [Section3] 논리, 사고의 흐름잘 읽히는 코드를 위한 방법에 대해 학습코드의 depth를 줄여 사고의 과정을 줄이기공백을 활용해 적절한 의미 나누기부정어 최대한 사용하지 않기NPE에 대한 처리, 의도한 예외와 예상하지 못 한 예외에 대한 구분Optional의 적절한 활용 [Section4] 객체 지향 패러다임객체 지향의 설계 원칙에 입각한 클래스 구분하나의 책임을 가지는 객체들 간의 협력으로 소프트웨어를 구성하자개념적으로만 알고 있던 객체 지향 설계 5대 원칙을 실제 코드에 적용해 보며 학습 [Section5] 객체 지향 적용하기상속은 부모와 자식간의 결합도가 높기 때문에 조합을 활용하는 것을 추천VO, 일급 컬렉션의 개념과 활용Enum 클래스의 활용변하는 것과 변하지 않는 것을 분리하여 추상화함으로써 OCP를 만족하는 코드를 작성설계할 때는 근시적, 거시적 관점에서 최대한 미래를 예측하고 예측이 틀린 경우를 대비해 언제든 돌아올 수 있도록 코드를 작성   1주차 미션Day2 미션일상의 추상적인 행위에 대해 구체적으로 표현해보는 간단한 미션이었다.'양치질'이라는 행위에 대한 과정을 구체적인 단계로 표현해보았다. Day4 미션학습한 내용에 입각해 코드를 리팩토링 해보는 미션SOLID라는 개념에 대해 본인만의 언어로 정리해보는 미션 https://exultant-timer-c4c.notion.site/Day4-1149027655a5808d8d7be5baa82ee0b4?pvs=41주차 회고학습해야할 내용이 생각보다 많아 퇴근 후 진도를 맞추기 버거운 부분이 있었다.이번 주는 휴일이 많아 이를 활용해 진도를 맞출 수 있었지만 이후로는 주말을 활용해 미리 학습할 필요가 있을 것 같다.객체 지향에 대해 개념만 학습하고 활용하는 방법에 대해선 알지 못했다. 이번 학습을 계기로 실무에서 적용해볼 수 있는 좋은 코드를 작성하는 방법을 많이 배울 수 있었다. 회사 코드를 작성하면서 배운 내용들을 되새기며 다른 팀원들의 입장에서 코드를 작성해나가야겠다.

워밍업클럽스터디

소망

[인프런 워밍업 스터디 클럽 2기 FE] 1주차 발자국

1주차 발자국[ 시작 ]javascript, react 스터디가 열린다는 소식에 참여하게 되었다. 회사와 병행할 수 있을까 라는 생각에 쉽지 않을거 같아서 고민하였지만, 한 발자국 더 성장할 수 있는 기회라 생각하여 신청을 하였다. 이번 기회로 javascript의 개념을 더 다잡고, react는 완전 초급 수준이지만 많이 알아갈 수 있었으면 좋겠다.일단 목표는 완주라도 해보자..! 이다. [ 강의 & 과제 ] 강의 정리var, let, const의 차이점과 스코프(=범위), 호이스팅var의 스코프는 함수 레벨에서만 존재하고, let&const의 스코프는 블록 레벨에서 존재호이스팅은 변수의 선언을 변수 범위 맨위로 끌고 오는 현상을 의미하는데, var는 호이스팅이 가능하고 let&const는 호이스팅이 불가능자바스크립트의 타입과 변환원시 타입과 참조 타입 2가지원시 타입 : Boolean, String, Number, null, undefined, Symbol참조 타입 : Object, Array=> 타입 확인 : typeof(변수)계산할 때 필요한 Math Object정말 많이 사용되는 Loop 종류for/in, do/while 사용법for/in은 객체의 속성을 따라 반복Window 객체window의 객체 안에 들어있는 속성 관련 (innerWidth, scrollY, location) 정보DOM (Document Object Model)메모리에 윕 페이지 문서 구조를 트리구조로 표현해서 웹 브라우저가 HTML 페이지를 인식하게 해줌HTML 요소를 선택하기 위한 메소드// 파라미터로 전달한 ID를 가진 태그를 반환 document.getElementById(요소아이디) // 파라미터로 전달한 name 속성을 가진 태그를 반환 document.getElementByName(name속성값) // 파라미터로 전달한 선택자에 맞는 첫 번째 태그를 반환 // class => .hello, id => #hello document.querySelector(선택자) // 파라미터로 전달한 태그이름을 가진 모든 태그들을 반환(배열) document.getElementsByTagName(태그이름) // 파라미터로 전달한 클래스 이름을 가진 모든 태그들을 반환(배열) document.getElementsByClassName(클래스이름) // 파라미터로 전달한 선택지에 맞는 모든 태그들을 반환(배열) document.querySelectorAll(선택자)createElement 메서드로 요소 생성 가능removeChild 메서드는 하나의 노드를 삭제할 때 사용replaceChild 메서드는 원래 있는 child를 삭제하고 새로운 child로 교체할 때 사용addEventListener 메서드는 이벤트가 발생했을 때 이벤트 리스너를 호출하기 위해서는 이벤트 리스너를 해당 객체나 요소에 등록해 주어야 함. Event의 종류Event Bubbling : 가장 깊게 중첩된 요소에 이벤트가 발생했을 때 이벤트가 위로 전달 되는 것Event Capturing : 가장 상단에 있는 요소에서 아래로 이벤트가 내려오는 것이벤트의 3단계 흐름 (캡처링 단계 > 타킷 단계 > 버블링 단계)Event Delegation : 하위 요소의 이벤트를 상위에서 제어 this (bind, call, apply)메서드, 함수, constructor, 화살표 함수에서의 this는 각각 다른 객체를 가리킨다.call, apply, bind를 이용한 함수 호출 방법이 있다.삼항 연산자Event Loop 동기 / 비동기 : 동기(Sync)는 순차적, 비동기(Async)는 비순차적 setTimeout : 만료된 후 함수나 지정한 코드 조작을 실행하는 타이머를 설정setTimeout(() => { console.log('2'); }, 3000);위의 소스가 동작하는 원리 => 자바스크립트 엔진, Web APIs, Event Loop, Callback Queue Closure구조 분해 할당 (Destructuring)let a, b, rest; [a, b] = [10, 20]; console.log(a); // 10 [a, b, ...rest] = [10, 20, 30, 40, 50]; console.log(rest); // [30, 40, 50]전개 연산자 (Spread Operator) Map, Filter, Reduceundefined, nullundefined : 아무 값도 할당받지 않은 상태null : 비어있는 존재하지 않는 값변수에 의도적으로 값이 없다고 할 때는 null을 사용얕은 비교 VS 깊은 비교얕은 비교 : 숫자, 문자열 등 원시 자료형은 값을 비교.깊은 비교 : 객체의 경우에도 값으로 비교. Object depth가 깊지 않은 경우에는 JSON.stringify() 사용하고, 깊은 경우에는 lodash 라이브러리의 isEqual() 사용 얕은 복사 VS 깊은 복사얕은 복사 : spread operator, Object.assign 이외에도 Array.from(), slice도 얕은 복사Object.freeze 메서드로 객체를 동결시켜서 기존 객체가 변경되지 못하게 해줌.깊은 복사 : 주로 lodash, Ramda 등 라이브러리 이용IIFE (Immediately Invoked Function Expression)즉시 실행 함수 표현은 정의되자마자 즉시 실행되는 함수 과제 정리첫번째 과제로 음식 메뉴 앱을 만들었다GitHub URL => food_menu[ 기능 요구사항 ]버튼을 누르면 버튼 type에 해당하는 메뉴들이 화면에 뿌려진다. [ 고민했던 부분 ]버튼을 누를 때마다 유동적으로 HTML의 부분이 변경되어야 하는 부분을 고민했었던거 같다.요소를 생성하고 삭제하고 부모의 요소 아래에 append하여 DOM을 만들었고, 없어져야 하는 부분은 removeChild를 이용해서 없애주고 새로 생성하는 방식으로 진행하였다.처음 web을 열었을 때 모든 메뉴들이 나오게 하기 위해 첫 실행 시 페이지 로드하는 함수를 넣어주었다.[ 회고 ]DOM을 조작해 본 적이 많지 않아서 이 부분이 익숙하지 않았다. 이번 과제를 계기로 DOM에 대해서 많이 찾아보고 알아갔던 시간이었고, 기본기에 부족함을 느껴 DOM의 개념에 대해 좀 더 공부해야할 거 같다.Data 부분을 배열로 가져왔는데 json 형식으로 변경해서 값을 가져오는 방식으로 변경해야겠다.두번째 과제로 가위 바위 보 게임을 만들었다.GitHub URL => 가위바위보앱[ 기능 요구사항 ]가위, 바위, 보 각각의 버튼을 누르면 플레이어의 선택으로 저장되고, 컴퓨터는 Random 함수를 이용해 결정플레이어와 컴퓨터의 값을 보고 비교하여 승, 패, 무승부 결정버튼을 한번씩 누를때마다 횟수를 한개씩 차감[ 고민했던 부분 ]게임이 끝나면 가위바위보의 버튼 부분이 사라지고, 게임 결과와 함께 다시 시작 버튼이 나오는 부분을 어떻게 하면 효율적으로 할 수 있을까 고민했다. 게임 결과 부분만 게임이 끝나면 나오게 요소를 생성해주고 다시 시작을 누르면 요소를 삭제하는 방식으로 진행하였다.[ 회고 ]현재는 결과만 표시되게 되는데, 플레이어와 컴퓨터의 결과가 나오기 전에 결과 표시하는 부분에 애니메이션을 넣어 이미지가 랜덤 돌아가게 표현하고 싶다. [ 1주차 회고 ]1주차에는 javascript 관련 강의와 과제를 진행하였다. 아직 못 들은 강의가 있고, 과제도 몇 개는 하지 못했다. 시간 날 때마다 강의를 듣고 과제도 하였는데 생각보다 시간도 많이 필요했고 계획에 맞게 못한 거 같아서 너무 아쉽다. 그래도 이번주에 들은 강의와 과제한 것으로 알게 된 점도 많이 있었다. 밀린 강의와 과제가 있지만 열심히 해서 끝까지 완주하고 싶다.

프론트엔드인프런워밍업클럽프론트엔드스터디

채널톡 아이콘