블로그

whffkaos007

워밍업 클럽 2기 BE 클린코드&테스트 - 회고 2회

 해당 회고는 박우빈님의 'Readable Code : 읽기 좋은 코드를 작성하는 사고법' 강의를 참조하여 작성했습니다. 2주차 회고인데 까먹고 이제야 씁니다 . . . 남은 기간에는 좀 더 열심히 참여해서 많이 얻어 가겠습니다!   기억하면 좋은 조언들능동적 읽기학습 내용을 빠르게 체득할 수 있는 방법은 직접 적용해 보는 것이다. 실습을 통해 이론으로 얻은 지식만의 부족함을 채울 수 있으며 결과를 직접 확인 가능하여 크게 와닿는다. 이처럼 클린 코드에 대한 견문과 견해도 직접 적용해 봐야 시야를 기를 수 있다.모든 것을 한 번에 보기는 어려우니 직접 하나하나 리팩토링 하면서 이해하기리팩토링을 통해 도메인 지식을 늘리고 작성자의 의도를 파악하도록 노력하기리팩토링을 무서워할 필요가 없다. git reset을 통해 언제든지 복구 가능하니 잘못된 코드를 작성하더라도 괜찮다. 결국 직접 시도해야지만 성장할 수 있다. 오버 엔지니어링모든 것에는 오버 엔지니어링이 생길 수 있다. 보여준 예시처럼 체스 게임을 구현했을 때, 너무 매달리지 않아도 된다. 체스란 게임은 몇 백년 간 변하지 않았다. 체스란 게임만 봤을 때, 끝없는 리팩토링과 효율성을 고려하는 것이 옳을까?보통 서비스는 발전하기에 우리는 추후 수월한 유지보수를 하기 위해 클린 코드를 고려해야 한다. 만약 단발성이나 지속 가능성이 없다면 적절한 타협점을 찾으면 된다.구현체가 하나인 인터페이스인터페이스 형태가 아키텍처 이해에 도움을 주거나, 근시일 내에 구현체가 추가될 가능성이 높다면 인터페이스를 적용할 의미가 있다.하지만 구현체를 수정할 때마다 인터페이스도 수정해야 한다.인터페이스이므로 코드 탐색에 영향을 주고 필요 이상으로 애플리케이션이 비대해질 수 있다.너무 이른 추상화정보가 숨겨지기 때문에 복잡도가 높아진다.후대 개발자들이 선대의 의도를 파악하기 어렵다.이처럼 클린 코드는 절대적인 법칙이 아니다. 우리는 필요에 의해 적용해야 한다. 이러한 견문은 경험에 따라 달라지니 부족하다면 열심히 적용해보자. 은탄환은 없다 클린 코드는 은탄환이 아니다. 실무 상황에서는 금전적 이익이 필수적이다. 그렇기에 고민에 빠진다.지속 가능한 소프트웨어 품질 VS 기술 부채를 안고 가는 빠른 결과물대부분의 회사는 돈을 벌고 성장해야 하고, 시장에서 빠르게 살아남는 것이 목표이다.이런 경우에도, 클린 코드를 추구하지 말라는 것이 아니라, 미래 시점에 잘 고치도록 할 수 있는 코드 센스가 필요하다. 결국은 클린 코드의 사고법을 기반으로 결정된다.이처럼 우리는 적정선을 찾을 수 있는 능력이 필요하다. 급하게 만들어 품질이 낮은 결과물에 대해서는 주석을 통해 추후 개선사항을 남기듯 상황에 맞는 합의점을 찾아야 한다.하지만 이는 클린 코드에 대한 이해와 경험이 충분해야 찾기 쉽다. 적정 수준을 알기 위해 극단적으로 사용해보는 것이 도움이 될 것이다. 예시로 망치만 쓰는 초보 목수는 모든 작업에 망치만 사용할 것이다. 망치밖에 쓸 줄 모르기 때문이다.망치와 톱을 다룰 줄 아는 숙력자 목수는 상황에 적절한 도구를 사용할 것이다. 나무를 자르는데 당연히 톱을 사용한다. 클린 코드도 마찬가지이다. 상황에 대한 판단이 가능한 숙력자가 되기 위해 극단적으로 숙력될 때까지 사용하자.   개선할 점실제로 리팩토링한 것과 강사님이 리팩토링한 부분과 차이를 보면서 보는 관점이 다르다는 것을 체감할 수 있었습니다. 제가 리팩토링하면서 익숙치 않아 옳은 리팩토링인가에 대한 의문은 있었습니다. 그래도 리팩토링에 대한 이유를 계속 생각하면서 하니 비교했을 때, 다시 개선해야 할 부분에 대해 인지할 수 있어 좋았습니다. 다른 말로는 오늘 리팩토링한 것을 내일 보라는 얘기를 해주셨는데 확실히 다음날 보니 생각치 못했던 부분에 대한 새로운 시야가 보여 마음에 와닿았습니다.많이 부족하지만 계속 연습해서 저만의 견해가 담긴 클린 코드를 작성할 수 있도록 노력하겠습니다. 

백엔드클린코드읽기좋은코드

whffkaos007

워밍업 클럽 2기 BE 클린코드&테스트 - 회고 1회

해당 회고는 박우빈님의 'Readable Code : 읽기 좋은 코드를 작성하는 사고법' 강의를 참조하여 작성했습니다. 범위는 섹션 1 ~ 4 입니다.회고와 같은 정리는 가끔 귀찮기도 했지만 결과물에 대한 정리와 점검할 수 있는 시간을 준다고 하니 좋은 마음으로 기록하는 습관을 기르겠습니다! 미션   public boolean validateOrder(Order order) { if(notExistItemsFrom(order)){ // 주문에 상품 목록이 존재하면 log.info("주문 항목이 없습니다."); return false; } if (isNotVaildTotalPrice(order)) { // 총액이 유효한 값인지? log.info("올바르지 않은 총 가격입니다."); return false; } if (hasNotCustomerInfoFrom(order)) { // log.info("사용자 정보가 없습니다."); return false; } log.info("주문 항목이 없습니다."); return true; } private static boolean hasNotCustomerInfoFrom(Order order) { return !order.hasCustomerInfo(); } private static boolean isNotVaildTotalPrice(Order order) { return order.getTotalPrice() <= 0; } private static boolean notExistItemsFrom(Order order) { return order.getItems().size() == 0; } 주문에 대한 검증 로직1. 주문 안에 상품이 존재하는가? 없다면 잘못된 주문으로 판별2. 상품의 가격이 1원 이상이라면 정상 처리 / 아니라면 잘못된 주문으로 판별3. 주문에 대한 사용자 정보가 있어야 한다. 없다면 잘못된 로직이다. 적용할 수 있는 읽기 좋은 코드 방식1. 사고의 depth 줄이기2. 부정구 지양하기3. 최대한 추상적으로 접근하기 ( getter로 직접 접근하기 X)4. early return 사용하기 각 조건을 모두 통과해야 유효한 주문이라는 결과를 도출해야 한다. 따라서 비즈니스 로직을 지키며 위 리팩토링 기준을 모두 적용하려 했으나 'not'과 같은 부정어를 사용했다. 이에 대한 이유if 조건 안에 && 처리를 하여 긍정구로 표현하려 했으나 조건이 길어지면 오히려 기억해야 할 정보가 많을 거 같아 이와 같이 부정구를 사용하지만 depth와 if문마다 하나의 조건만 담기 위해 이와 같이 리팩토링했다.   인상적인 부분 테스트 코드와 클린 코드에 대한 중요성은 들어봤지만 기능 구현조차도 쉽지 않다 보니 평소 읽기 좋은 코드에 대해 접해볼 시도조차 없었습니다. 강의 도입 섹션에서는 읽기 좋은 코드의 중요성에 대해 설명하시는데 클린 코드에 관한 새로운 관점(?)도 알 수 있어 좋았고 읽기 좋은 코드 작성에 대한 이유와 실제 적용을 통해 진행해서 더 마음에 와닿았습니다.  학습 정리강의 내용과 제가 따로 정리한 부분이 섞여 있으니 참고해주세요.방대한 강의 내용과 강의에서 제공한 모든 내용 제시를 피하기 위해서 인상 깊었던 섹션 1,2 위주로 정리하겠습니다. 1. 클린 코드와 추상 관계 왜 클린 코드를 추구하는 것일까?결국, 클린 코드는 읽기 쉬운 코드이며 적절히 추상화가 이뤄진 코드이다. 이러한 코드는 유지 보수에 들어가는 시간과 비용을 절약해준다.극단적으로 확장 가능성이 없거나 그 순간에 개인만이 서비스에 대한 코드에 접근하고 작성한다면 보편적인 클린 코드 대신 본인이 알아보기 쉬운 형태의 코드로 작성하는 것이 더 합리적일 수도 있다.하지만 이와 같은 경우보다는 거의 없기에 클린 코드를 추구하는 것이다. 프로그램의 정의는 무엇일까?다양한 의미가 있겠지만 다음과 같이 정의할 수 있다.‘프로그램 = 데이터 + 코드’데이터는 어떠한 정보 자체를 의미하고 코드는 어떠한 논리적 행위를 의미하며 데이터와 데이터 간, 데이터와 코드 간 등 여러 관계에서 논리적 행위가 일어날 수 있다. 그럼 데이터와 코드는 실제 우리가 작성하는 코드에서는 어떤 것을 의미할까?데이터는 객체, 클래스가 가지는 값이 있으며 객체가 어떤 행위를 수행하는 의미를 가진 메서드 선언부를 나타낼 수 있다.(반환값, 파라미터, 메서드명 등)코드는 메서드의 내부 행위 값이 있고 크게는 코드 간 여러 복합적인 메서드 간 상호 작용으로도 볼 수 있다.위 코드에 대한 예시를 보면 calculateChangeMoney 메서드 선언부와 Person 필드 등이 데이터가 볼 수 있고 calculateChangeMoney, donamteMoney 등 메서드에 내부 로직을 코드로 볼 수 있다. 도대체 읽기 좋은 코드에 대한 객관적인 기준이 뭐야?읽기 좋다는 것은 바로 추상과 구체에 의해 나타난다.하나의 예시를 보자.<aside> 💡나는 누군가 쳐다본다. 일반적인 ‘보다’ 라는 느낌과는 다르다. 주위에 있으면 한순간도 놓치지 않고 어떤 표정을 짓는지, 무엇을 하는지 바라보게 된다.이 사람이 슬퍼하기 보단 웃고 행복했으면 좋겠고 이 사람을 생각하면 가슴이 두근두근 뛴다. 슬퍼하면 나도 슬프고 행복해 보이면 괜히 나도 행복해진다.이 사람이 좀 더 행복할 수 있다면 내가 좀 더 손해를 봐도 좋다. 손해를 보면 기분이 나쁘거나 우울한 것과 같이 부정적인 생각이 들어야 하는데 오히려 손해를 보는 것이 더 좋다.</aside>이러한 내용은 무엇을 나타낼까? 하나의 단어로 표현할 수 있다.‘사랑’ 이란 단어로 표현 가능하다. 여기서 ‘사랑’은 위 내용에 대한 추상이며 위 내용은 ‘사랑’이란 단어에 대한 구체이다.2가지 문장 중 어떤 것이 읽기 편하고 합리적이라 생각하는 가?<aside> 💡1번너 요즘 사랑하는 사람이 있어?2번너 요즘 어떤 사람을 보면 가슴이 콩닥콩닥 뛰고 그 사람만 쳐다 보고 싶고 다 해주고 싶고 손해를 봐도 전혀 아쉽지 않고 행복하길 바라고 감정을 나누고 싶은 사람이 있어?</aside>보편적으로 1번이 읽기 편하고 합리적일 것이다.여기서 추상과 구체의 관계를 알 수 있으며 적절한 추상화는 문장을 이해하는 데 적은 비용과 시간이 든다. 쉽게 이해할 수 있기 때문이다.이러한 추상과 구체는 우리가 작성하는 코드에도 적용되고 있다. 결론적절한 추상화는 복잡한 데이터와 복잡한 로직을 단순화하여 이해하기 쉽도록 돕는다. = 읽기가 좋다.우리는 추상과 구체의 관계를 알 수 있으며 추상이 어떤 역할을 하는 지도 알 수 있었다. 추상화를 하면 우리는 복잡한 것을 쉽게 이해할 수 있으니 무조건 추상화를 해야 할까?무분별한 추상은 좋지 않다. 과한 추상은 구체를 유추하지 못할 수 있다. 지속적으로 언급한 ‘적절한 추상화’만이 읽기 좋은 효과를 가져올 수 있다.어떠한 경우가 추상으로부터 구체를 유추하지 못할까?<aside> 💡나는 밤이 좋아졌잘싸나는 친구랑 샤우팅 갔어 </aside>위 3가지 예시에 구체적인 의미를 알 수 있는가?1번은 먹는 밤인지 시간에 따라 나타나는 밤인지 알 수 없다.2번은 ‘졌지만 잘 싸웠다’라는 의미지만 과하게 줄인 탓에 알 수 없었다.3번은 샤우팅이라는 단어의 의미를 알 수 없었다. 소리 지르는 행위에 대한 미미한 유추만 가능하다.위 예시에 대한 문제점이다.추상화 과정에서 중요한 정보를 부각시키지 못했다.상대적으로 덜 중요한 정보를 남기고 중요한 정보는 제거했다.해석자가 동일하게 공유하는 문맥이 없다.중요한 정보의 기준이 다를 수 있다.도메인 영역 별 추상화 기준이 다를 수 있다.즉, ‘잘못된 추상화’는 오히려 추상화 안 한 것보다 못할 수 있다. 야기하는 side-effect는 생각보다 정말로 크다.‘적절한 추상화’는 해당 도메인 문맥 안에서, 정말 중요한 핵심 개념만 남겨서 표현하는 것이다.이름 짓기로 추상화 하기메서드와 추상화 한 문단의 주제는 반드시 하나다.잘 쓰여진 글이라면, 한 문단의 주제는 반드시 하나다. 0개도 2개도 아닌, 무조건 1개이다.실제로 국어/영어 시험에서도 주제가 1개가 아니라면 답이 오직 1개라고 정의하기 힘들다.문장과 문장에 대한 주제는 마치 코드에서의 메서드 선언부와 메서드 로직과 같은 역할을 한다.메서드 이름으로 구체적인 내용을 추상화한 것이다. 다른 예시를 보자.메서드의 로직 내부에서는 2가지 이상의 일을 하고 있다.메서드에서 수행하는 일산책하기, 은행가서 현금 인출하기, 음식점에서 밥 먹기, 책 구매하기오른쪽 메서드를 보자. 더 큰 맥락 안에서 포괄적인 의미를 담았다.즉, 잘 쓰여진 코드라면 하나의 메서드의 주제는 반드시 하나이다.메서드 선언부반환타입메서드 시그니처에 납득이 가는, 적절한 타입의 반환값 돌려주기→ 반환 타입이 boolean인데, 이게 이 메서드에서 무엇을 의미하는거지?void 대신 충분히 반환할 만한 값이 있는지 고민하기→ 반환값이 있다면 테스트도 용이해 진다. 결과값이 없다면 상태와 행위 중, 행위밖에 검증할 수 없다.메서드명추상화된 구체를 유추할 수 있는, 적절한 의미가 담긴 이름파라미터와 연결지어 더 풍부한 의미를 전달할 수 있다.파라미터타입, 개수, 순서를 통해 의미를 전달외부 세계와 소통하는 창String createDailyShopKey(String shopId, String localDateString){ return String.format("%s_%s", shopId, localDateString); } String createDailyShopKey(String shopId, LocalDate sellingDate){ return String.format("%s_%s", shopId, sellingDate.toString()); } 위 두 메서드 중 어떤 것이 더 잘 추상화를 했을까?//S34_2024-06-01 String shopId = "S34"; LocalDate today = LocalDate.of(2024, 6, 1); //1 String dailyShopKey = createDailyShopKey(shopId, today.toString()); //2 String dailyShopKey = createDailyShopKey(shopId, today); 정답은 2번이다. 이유가 뭘까?이유날짜를 String 값으로 나타낼 때, 다양한 형식이 있다. 2024-06-01, 2024.06.01 등 어떤 형식의 문자열로 넘길지 고민하게 된다.따라서 LocalDate 자체로 넘기면 날짜의 의미를 가진 LodatDate 구체화된 타입을 넘기면 된다라는 명확함을 인지할 수 있다.sellingDate와 localDateString의 의미를 보면 메서드 행위에 대한 의미를 보면 sellingDate가 더 많은 정보를 제공하므로 파악하기 쉽다.localDateString에 비해 sellingDate는 판매날짜의 의미를 담고 있다. 추상화 레벨 서점에 위와 같이 진열대에 책이 나열되어 있다. 여기는 여러 책이 진열되어 있는 공간이며 책의 제목이란 추상을 통해 책의 내용을 유추할 수 있다. 그런데 책의 구조인 제목, 목차, 내용 순이 아닌 단순 서류 뭉치로 이루어진 책 하나가 있다.이상하지 않는가? 서류 뭉치를 본 순간에 책인지, 그냥 단순 서류 뭉치인지 알 수 없다. 저 서류 뭉치의 존재에 대해 의문이 들고 이해하는데 비용이 발생한다.void method(){ ....... T t = extracted(p); .... } T extracted(P p){ ...something.... } 우리는 메서드 구현부를 확인할 때, 위처럼 extracted 메서드와 같이 추상화된 내부 메서드를 본다. 추상화된 메서드명의 주제에 대해 더 궁금하면 해당 메서드 내부에 들어가 확인할 것이다.이는 외부 세계와 내부 세계로 나뉠 수 있으며 method 내부에 메서드 선언부로만 표현된 extracted(p)가 경계가 된다.이는 외부 세계는 추상화 레벨이 높고, 내부 세계는 추상화 레벨이 낮음을 의미한다. 당연히 메서드 구현부에는 메서드 선언부에 대한 구체적인 내용이 있기 때문이다.하나의 세계에서는 추상화 레벨이 동등해야 한다.우리는 진열된 책을 예시로 봤다. 코드로 직접 봐보자.public static void main(String[] args) { showGameStart(); 10 initializeGame(); 10 showBoard(); 10 .... if (gameStatus == 1) { 5 System.out.println("지뢰를 모두 찾았습니다. GAME CLEAR!"); break; } ..... 10 } 10, 5는 예시로 추상화 단계를 수로 표현했다. 10이라는 추상화 단계를 가다가 ‘gameStatus == 1’ 이라는 구체에 가까운 5라는 추상화 단계를 만나며 코드를 이해하는데 혼란을 줄 수 있으며 추가적인 논리가 더 필요로 하다.그렇기에 추상화 단계를 맞춰주는 것은 중요하다.   진행할 점강의의 양이 매우 방대하여 깔끔하게 정리하기 쉽지 않은 거 같다. 추상과 구체의 관계에 대해 학습했으니적절한 추상화를 통해 내용을 정리해서 상대방에게 이해하기 쉬운 글을 제공할 수 있게 연습해봐야겠다.    

백엔드읽기좋은코드클린코드

gotjd9773

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

개요테스트 코드 학습을 시작했다.Practical Testing : 실용적인 테스트 가이드3주차 공부한 내용수강한 강의 영상은 얼마 안 되는 거 같지만, 러닝 타임이 어마어마하다.확실히 긴 러닝타임의 영상은 힘들다.그래도 공부할만한 내용을 배우고 있다고 되뇌이며 강의를 수강했다. 배운 것들1. TDD 적용하기TDD를 처음 해본 것은 아니다.TDD 주제 책들을 읽은 적도 있고, 직접 해 보기도 했다.TDD를 처음했을 때 깨달은 것은 "단일 클래스의 메소드를 TDD로 개발하는 것은 어렵지 않으나, 여러 계층이 있는 스프링 프로젝트에서 TDD를 적용하는 건 어렵구나. 어떻게 적용하지?" 였다. 강의를 통해서 스프링 프로젝트에서 TDD를 적용하는 방법을 배울 수 있었다. 2. DisplayName을 작성하는 법테스트 메서드의 이름이나, DisplayName을 배웠다.항상 중구난방, 기준도 없이 작성해서 고민이 많았던 내용인데,고민 해결! 3. 재고 차감시 재고가 있는지 두 번 체크하는 이유서비스에서 재고 체크 한 번, 엔티티 객체 안에서 재고 체크 한 번동일한 로직이 두 번 반복해줘야 하는 이유를 배울 수 있었다. 4. 컨트롤러에서 하는 유효성 검증, 서비스에서 하는 유효성 검증유효성 검증을 컨트롤러에서만 하는 게 아니라 계층에 맞는 유효성 검증이 있다는 것을 배웠다.  미션이번 주차에는 Day 12. 미션이 있었다. Day 12. 미션 - 읽기 좋은 코드 강의 예제 코드 단위 테스트 작성하기Readable Code: 읽기 좋은 코드를 작성하는 사고법 강의의 예제 프로젝트로 지뢰찾기와 스터디카페가 있다.둘 중 하나를 선택하여 3개의 클래스, 7개의 단위 테스트를 작성하는 것이었다.나는 스터디카페를 선택하였다.강의에서 배운 내용을 그대로 적용만 하면 되는 미션이라 수월하게 마칠 수 있었다. 마무리다음 주차 부터는 Mocking 에 대해서 배우게 된다.항상 테스트 코드를 작성할 때마다, Mocking 을 사용할 때마다 찝찝함을 느끼곤 했다.이번 기회에 제대로 정리하고 가야겠다.

백엔드읽기좋은코드클린코드워밍업클럽테스트

gotjd9773

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

개요2주차 종료!Readable Code: 읽기 좋은 코드를 작성하는 사고법 을 완강했다.2주차 공부한 내용목요일에 Readable Code 강의를 완강하고, 금요일 부터는 Practical Testing 강의를 수강 시작했다. 배운 것들1. 일급 컬렉션일급 컬렉션이란 걸 처음 알게 되었다.일급 시민과 컬렉션(List, Set, Map)이 합쳐진 개념이다.컬렉션을 가공하는 로직을 캡슐화할 수 있는 장점이 있다.처음 접하는 개념이라 코드로 적용하는 하는 부분에서 어려움을 느꼈다.그렇지만, 잘만 사용하면 엄청 유용한 기법이라는 생각이 든다. 2. supports()이 메서드를 Spring Security 학습하면서 많이 봤었다.그 때는 이게 왜 필요하지 했었는데, 강의를 보면서 궁금증이 해소되었던 것 같다.다형성, 객체지향에 대해서 좀 더 가까워진 느낌? 3. 주석을 어떨 때 써야하는지주석은 웬만하면 사용하지 않는 편이 좋다고 생각했다.하지만, "코드에 히스토리, 개발자의 의도를 전부 녹일 수 없을 때"에는 주석을 써야 한다는 걸 배웠다. 4. 메서드 배치 순서이거 진짜 유용했다.메서드를 어떤 기준으로 배치해야 하는지 고민이 많았었는데,덕분에 기준을 세울 수 있었다. 5. sonarlint정적 코드 분석 도구로, 인텔리제이에서 플러그인 형태로 사용 가능하다.앞으로 Stack 과 Queue 를 쓸 일이 있을 때는 무조건 Deque을 사용할 거다.sonarlint가 Deque을 사용하라고 추천해줬음. 미션이번 주차에는 Day.7 미션이 있었다. Day.7 미션 - 스터디 카페 프로젝트 리팩토링 실습하기강의에서 배운 것을 토대로 실제로 리팩토링하는 실습이었다.추상화 레벨, 일급 컬렉션, DIP, SRP 를 염두에두고 리팩토링 했다.생각보다 쉽지 않았다.스스로 해보고 답지(강의)를 보니 갈 길이 멀어보인다.나의 가장 큰 문제점은 주어진 틀에서만 해결하려고 한다는 점이다.그래서 새로운 객체를 만든다든지, 기존의 if 문들을 다른 구조로 변경하는 것에 두려움을 느끼는 것 같다.문제를 마주할 때 넓게 보는 연습이 필요한 것 같다. 차분히.리팩토링을 더 잘하기 위해서 섹션 8 - 기억하면 좋은 조언들 - 능동적 읽기 강의 내용을 적용하면 좋을 듯 하다. 공백으로 단락 구분하면서 읽기메서드와 객체로 추상화하면서 읽기주석으로 이해한 내용 표기하면서 읽기Day.7 미션을 수행할 때 위의 조언들을 적용했더라면 좀 더 나은 결과물을 얻을 수 있었을 것 같다. 마무리2주 동안 Readable Code 보면서 많이 배웠다.배운 내용들을 체화시키려면 좀 더 노력해야 할 것이다.일단은 3주차부터 테스트 코드 진도를 나가야하니 테스트 코드에 신경을 쓰도록 하고테스트 코드를 빨리 끝낼 수 있다면, Readable Code의 내용을 복습하면 좋겠다. 

백엔드읽기좋은코드클린코드워밍업클럽객체지향추상화

yesrin

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

인프런 1주차가 끝났다. 강의 수강과 과제를 제때제 하지 못해서 100% 얻어 가지 못하는 것 같아 속상하지만..!2주차는 1주차 보다 더 열심히 해보고자 한다! (더 이해하고, 기록하고, 나만의 언어로 설명하기) 강의를 들으며 기억에 남았던 부분을 정리하며 마무리해보려고 한다. 추상 (抽象)도메인 용어 정리의 필요성새 프로젝트를 시작하기 이전에 팀원들과 코드컨벤션을 정해본 경험이 있었다. 도메인 용어같은 경우에는 눈치껏 기존 프로젝트에 따라서 사용하고 있었는데 정리하고 시작한다면 모두에게 도움이 될것 같다. 메서드 선언부메서드 시그니처 : 메서드명 + 파라미터 파라미터의 타입, 개수, 순서를 통해 의미를 전달할 수 있다는 점을 기억하자. 추상화 레벨하나의 세계 안에서는, 추상화 레벨이 동등해야 한다."서점의 책들 사이에 책 제목이 없는 문서 뭉치가 껴있다". 라는 강사님의 비유가 인상적 이였다.추상화 레벨이 맞지 않는다면 읽는 사람은 고민을 하게 될 것이다. 논리, 사고의 흐름Early returnvoid일 경우에는 early return 할 생각을 못하고 있었는데 코드를 이해하기에 return 이 있는 편이 좋겠다. Optional을 해소하는 방법분기문을 만드는 isPresent()-get() 대신 풍부한 api를 사용하자.orElseGet(), orElseThrow(), ifPresent(), ifPresentOrElse() 객체 지향 패러다임객체를 만드는 처음부터 getter, setter을 만들지 말아라. SOLID SRP 단일책임원칙 : 이 객체가 하나의 책임만을 가지고 있는지 질문을 던져야 한다.OCP: 확장에는 열려있고, 수정에는 닫혀있다. =>새로운 기능 또는 요구사항이 생겼을때 기존 코드가 과도하게 변경 된다면 OCP 를 지키지 못한것이다.LSP :상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다.ISP : 자신이 사용하지 않는 인터페이스에 의존하면 안된다. => 인터페이스를 잘게 쪼개라!DIP : 의존성 역전 원칙   어려운 이론이지만 코드를 통해서 설명해 주셔서 이해하기 편했다. ++ 더 듣고 추가 예정 이번 강의를 들으면서 내가 작성했던 코드를 어떻게 더 읽기 좋은 코드로 만들어어야 할지 알게 되었고, 동료들이 작성했던 코드도 더 이해 할수 있게 되었다. 2주차도 화이팅!   강의 : Readable Code: 읽기 좋은 코드를 작성하는 사고법 (박우빈)      

읽기좋은코드

cosmos

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

1주차 동안 학습했던 내용 정리하나의 클래스와 거대한 main 메서드에 작성된 지뢰찾기 게임을 강의를 수강하면서 읽기 좋은 코드로 수정하는 과정을 단계적으로 학습했다.두 번째 섹션에서는 추상이라는 주제로 시작하여 구체와 추상에 대한 정의를 배우고, 추상화하는 과정에서 다음과 같은 방법을 학습했다.의미를 적절하게 전달하는 메서드, 변수명 짓기메서드 선언부에 꼭 필요하고, 적절한 파라미터 전달하기하나의 메서드 안에서 추상화 레벨을 동일하게 맞추기일정한 의미를 가지는 숫자나 문자열을 상수로 추출하기세 번째 섹션에서는 코드를 읽는 과정에서 코드 내용을 기억하기 위해 뇌의 메모리를 사용한다는 사실에 대해서 인지할 수 있었고, 이 메모리 사용량을 줄일 수 있는 다음과 같은 방법을 학습했다.Early return으로 리턴해야 될 값을 바로 바로 반환하기코드 중간 중간 의미가 나뉘는 부분에 공백 라인을 삽입하기부정 연산자를 사용을 지양하고, 메서드 이름으로 부정의 의미 전달하기사용자가 서비스를 이용할 때 성공적인 시나리오대로 이용할 것이라는 생각을 버리고, 적절한 예외를 이용해 적절하지 않은 사용에 대해서도 방어적인 코드 작성하기1주차 미션에 대한 회고Keep첫 번째 미션을 기한 안에 제출했다.두 번째 미션은 기한 안에 제출하지 못했지만, 1주차가 끝나기 전에 제출했다.Problem1주차 미션은 크게 어려운 점이 없었다.TRY함께 스터디를 진행하는 다른 개발자분이 제출한 풀이법과 내 풀이법을 비교하면서 부족한 부분을 추가적으로 학습하자.1주차 학습에 대한 회고Keep워밍업 클럽 스터디 2기에 참여했다.스터디를 통해 평소 학습하고 싶었던 내용에 대해서 학습할 수 있는 기회를 잡았다.Problem두 번째 미션을 기한안에 제출하지 못했다.강의를 수강하는 동안 집중력일 잃고 자주 핸드폰을 확인했다.TRY미션 제출 기한을 꼭 지키자.미션, 발자국을 마감 시각에 맞춰 제출하는 것이 아닌 여유를 갖고 미리 미리 진행해서 제출 마감 전날에 제출한다.미션, 발자국 마감일에는 제출했던 내용을 다시 곱씹으며 부족한 부분이 없는지 체크한다.강의를 수강하는 동안에는 핸드폰을 확인하지 않는다.학습 시간과 휴식 시간을 적절하게 안배해서 강의 내용을 최대한 많이 흡수하려고 노력하자.

백엔드백엔드읽기좋은코드발자국스터디

gotjd9773

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

개요인프런 워밍업 스터디 클럽 2기 백엔드(읽기 좋은 코드, 테스트 코드) 9/27 금요일 시작되었다.스터디 주제는 박우빈님의 강의인Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드이다.1 ~ 2주차에는 읽기 좋은 코드 강의를 수강하고, 3 ~ 4주차에는 테스트 강의를 수강 하게 되는데,이번 글은 1주차, 읽기 좋은 코드 강의를 수강하고 배운 것들을 정리해 보려고 한다. 1주차 공부한 내용발자국 작성을 위해 표로 정리했다. 생각보다 번거로운 작업이었다. 강의 하나 듣고 로그 기록하고...권장 진도표에 따르면, 섹션 5까지 1주차에 수강 하도록 되어 있는데,이번 주는 섹션 4까지가 한계였다. 생각보다 내용이 많았고, 한 번에 이해되지 않는 내용들은 복습해야 했다. 해결한 것 - 인텔리제이 한글 깨짐 이슈처음부터 난관을 겪었다.인텔리제이 한글 깨짐 이슈...강의에서는 지뢰찾기 게임을 콘솔 프로그램으로 구현이 되어 있고,콘솔에 출력되는 내용이 한글, 지뢰 모양, 네모박스 모양, 깃발 모양 등이 있는데,전부 깨져서 출력되었다.구글링을 통해 해볼 수 있는 것들은 다 해봤던 것 같다.그래도 안 되서 포기하려던 찰나, 유튜브에는 관련 내용이 없는지 살펴보았다.결국, 해결! (유튜브 만세!)Project Structure 에서 SDK와 Language level 을 17 버전으로 동일하게 맞춰주니 한글 깨짐 이슈가 해결되었다.기존에는 SDK는 21 버전이 적용되어 있었다.버전이 제대로 맞지 않으면 한글 깨짐 이슈가 일어나는구나를 깨달았다.  이미 알고 있던 것들1. 이름 짓기 이름을 잘 지어야 한 다는 것은 알고 있었다. 어려워서 그렇지...2. 메서드 추출 이거는 코드짤 때 열심히 활용하고 있다.Ctrl + Alt + M추가적으로 메서드로 추출할 때 주의사항을 설명해주셨는데 도움이 많이 되었다.메서드를 추출할 때마다 항상 주의사항 4가지를 점검해야겠다. 메서드 추출시 주의사항 4가지메서드명은 적절한가?혹시 메서드가 두 가지 일을 하고 있지는 않은가?파라미터는 적절한가?반환타입은 적절한가?왜 이 4가지를 주의 해야 하는지는 강의를 통해 확인하시라. 배운 것들1. 추상화 레벨 "하나의 세계 안에서는 추상화 레벨이 동등해야 한다." - 박우빈추상화 레벨을 동등하게 맞춰야 한다는 개념은 처음 알게 되었다.이해를 돕기 위해 들어주신 서점 비유가 와 닿았다.추상화 레벨을 맞추지 않는 것은 서점 주인이 책들 사이에 표지, 제목도 없는 종이 모음을 책 이랍시고 내놓는 것과 같다.서점에 들어갔는데 종이 모음을 보게 되면 많이 당황스러울 것 같긴 하다. ㅋㅋㅋ나는 이런 서점 주인이 되어서는 안되겠다고 다짐했다. 2. Early returnEarly return 이라는 용어는 처음 접했다.이거를 무의식적으로, 이런 용어가 있다는 것도 모른채 사용해왔던 것 같다.Early return을 사용하면 뇌 메모리의 부하를 줄일 수 있겠구나를 깨달았다. 3. orElse, orElseGet, orElseThrow의 차이자바 8 문법을 배울 때 한 번씩 사용해본 메서드들인데 이번에 제대로 정리할 수 있었다. 4. getter 사용 자제setter를 사용하지 말라는 것은 들어봤지만, getter도 사용 하지 않는 것이 좋다는 것은 처음 들었다.어쩔 수 없을 때는 getter를 써야 겠지만, 클래스를 설계할 때 무지성으로 getter를 선언하는 행동은 지양해야겠다. 미션인프런 워밍업 클럽 스터디는 강의 수강 뿐만 아니라 미션 수행도 해야 한다.이번 1주차에는 Day 2, Day 4 미션이 있었다. Day 2 미션 - 추상과 구체 예시일상 생활에서 추상과 구체에 대한 예시를 찾는 미션이었다.요즘 관심 있는 주제에서 예시를 찾으려고 했다.요즘 관심 있는 주제는 주식, 운동, 스타크래프트인데,운동 분야가 가장 설명하기 쉬워 보였고, 모든 사람이 알만한 스쿼트에 대해서 구체적으로 설명했다. Day 2 미션 답변 - 스쿼트를 구체 레벨에서 표현한다면?발을 어깨너비로 벌리고 무게중심을 발뒤꿈치에 두면서 무릎을 굽힌다.숨을 참고 복압을 유지한 상태로 엉덩이를 뒤로 밀며 허벅지가 지면과 평행해질 때까지 내려간다.하체 근육을 사용해 다시 상체를 들어 올린다.동작이 끝난 후 숨을 내쉰다. Day 4 미션 - 메서드 리팩토링 실습, SOLID 개념을 자신 만의 언어로1. 메서드 리팩터링 실습 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; }위의 메서드를 읽기 좋은 코드로 리팩토링 해보는 미션이었다.Early return, 추상화 레벨을 맞춰주기, 공백 라인, 부정어, 이름 짓기에 주의하며 리팩터링을 수행했다.아래 코드가 리팩터링을 거친 코드public boolean validateOrder(Order order) { if (order.getItems().isEmpty()) { log.info("주문 항목이 없습니다."); return false; } if (order.isTotalPriceInvalid()) { log.info("올바르지 않은 총 가격입니다."); return false; } if (order.hasNoCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } return true; }2. SOLID 개념을 자신만의 언어로견고한 객체지향 프로그램을 위해 제시된 개념인 SOLID를 자신만의 언어로 설명하는 미션이었다.글이 너무 길어지니까 이거는 생략하겠다. 아쉬웠던 점읽기 좋은 코드로 리팩터링하기 위해서는 테스트 코드가 꼭 필요하다.원래라면 테스트 코드를 짰을 테지만, 시간이 없었다는 핑계로 테스트 코드는 건너 뛰었다.하지만, 테스트 코드 없는 리팩터링이 오히려 시간을 더 잡아먹을 수 있고, 훨씬 개발자를 불안하게 만드는 것 같다.3주차부터는 테스트 코드를 본격적으로 배우게 될텐데 기대된다. 마무리100점 짜리는 아니었지만, 내 상황에서 최선을 다한 한 주였다.미션을 제 때 낼 수 있어서 기쁘다.2주차도 잘해보자. 

백엔드읽기좋은코드클린코드워밍업클럽객체지향추상화

채널톡 아이콘