일상/레벨업 독서 35

[내 코드가 그렇게 이상한가요?] 14장 리팩터링 : 기존의 코드를 성장시키는 기술

리팩터링이란?  실질적인 동작은 유지하면서, 구조만 정리하는 작업입니다.  실질적인 동작이 변하지 않았음을 확인할 수 있는 방법으로는 단위 테스트 등이 있습니다.    리팩터링 대상 코드는 아래와 같습니다.class PurchasePointPayment{ final CustomerId customerId; // 구매자의 ID final ComicId comicId; // 구매할 웹툰의 ID final PurchasePoint consumptionPoint; // 구매에 필요한 포인트 final LocalDateTime paymentDateTime; // 구매 일자 PurchasePointPayment(final Customer customer, final Comic comi..

[내 코드가 그렇게 이상한가요?] 13장 모델링:클래스 설계의 토대

시스템은 목적을 달성하기 위한 수단입니다. 그리고 모델은 시스템의 구성 요소들입니다.  모델이란 특정 목적 달성을 위해 최소한으로 필요한 요소를 갖춘 것입니다.    예시 - 온라인 쇼핑몰상품 매매를 시스템화한 것온라인 쇼핑몰은 매매가 효율적으로 이루어지게 도와줌    모델로 구분하기 전상품 classID상품영원가판매 가격제조년월일제조 업체보증 기간대응 통신 규격구성 부품ㅂ부품 재료부품 제조업자유통 기한소비 기한...    모델 별로 구분한 후 1) 주문 시의 상품 모델최소한으로 필요한 요소 - 상품ID, 상품명, 판매 가격, 재고 수량 등 주문 시의 상품 classID상품명판매 가격재고 수량...   2) 배송 시의 상품 모델최소한으로 필요한 요소 - ID, 크기, 무게 등 배송 시의 상품 classI..

[내 코드가 그렇게 이상한가요?] 12장 메서드(함수):좋은 클래스에는 좋은 메서드가 있다

[메서드 설계 방법] 1. 반드시 현재 클래스의 인스턴스 변수 사용하기다른 클래스의 인스턴스 변수를 변경하는 메서드는 좋지 않습니다. 응집도가 낮은 구조가 될 수 있기 때문입니다.   2. 불변을 활용해서 예상할 수 있는 메서드 만들기불변을 활용해서 예상치 못한 동작 자체를 막을 수 있게 설계하기 바랍니다.   3. 묻지 말고 명령하라메서드를 호출하는 쪽에서는 복잡한 처리를 하지 않는 것이 좋습니다.   (5장 참고)다른 객체의 내부 상태(변수)를 기반으로 판단하거나 제어하려고 하지 말고, 메서드로 명령해서 객체가 알아서 판단하고 제어하도록 설계하라는 의미입니다. 인스턴스 변수를 private으로 변경해서, 외부에서 접근할 수 없게 합니다. (setter, getter 주의!!)그리고 인스턴스 변수에 대..

[내 코드가 그렇게 이상한가요?] 11장 주석:유지 보수와 변경의 정확성을 높이는 주석 작성 방법

1. 내용이 낡은 주석 처음 개발 내용과 달리 이후에 사양이 변경되면서 주석까지 유지 보수하지 못한 경우입니다. 주석이 낡아 버리지 않게, 구현을 변경할 때 주석도 함께 변경하는 것이 좋습니다.  1) 주석은 실제 코드가 아님을 이해하기  2) 로직의 동작을 설명하는 주석은 낡기 쉽다코드의 동작을 그대로 설명하는 주석은 코드를 변경할 때마다 주석도 변경해야 할 것입니다. 만약 실수로 변경하지 않으면, 로직과 주석 사이에 괴리가 생깁니다.    2. 주석 때문에 이름을 대충 짓는 예메서드는 주석으로 설명을 추가하기보다, 메서드의 이름 자체를 수정하는 것이 좋습니다. 메서드의 가독성을 높이면, 주석으로 설명을 추가하지 않아도 됩니다. 그러면 내용이 낡은 주석이 생길 가능성도 줄어듭니다.     3. 의도와 ..

[내 코드가 그렇게 이상한가요?] 10장 이름 설계:구조를 파악할 수 있는 이름

1. 악마를 불러들이는 이름 class 상품 { public void 상품 예약(){ //예약과 관련된 로직 ... } public void 상품 주문(){ //주문과 관련된 로직 ... } public void 상품 출고(){ //출고과 관련된 로직 ... } public void 상품 발송(){ //발송과 관련된 로직 ... }}   [문제점] 거대해진 상품 클래스에 사양 변경이 발생하면 변경된 부분의 영향을 받아 동작에 버그가 생기지는 않는지, 상품 클래스와 관련된 클래스를 모두 확인해야 합니다.    [개선점] 1) 관심사 분리하기관심사 분리는 '관심사(유..

[내 코드가 그렇게 이상한가요?] 9장 설계의 건전성는 여러 악마

1. 데드 코드 - 실제로 실행되는 코드가 아니면 제거하자.    2. YAGNI 원칙 - 'You Aren't Gonna Need It.' 의 약자로 '지금 필요 없는 기능을 만들지 말라!' - 소프트웨어에 대한 요구는 매일매일 변한다.미리 예측하고 구현해도, 이러한 예측은 대부분 맞지 않다.예측에 들어맞이 않는 로직은 데드 코드가 된다.    3. 매직 넘버class ComicManager{ //생략 boolean isOk(){ return 60    - 설명이 없는 숫자는 개발자를 혼란스럽게 만든다.  class ComicManager{ /** 체험 구독 소비 포인트 */ private static final int TRIAL_READING_POINT = 60; ..

[내 코드가 그렇게 이상한가요?] 8장 강한 결합: 복잡하게 얽혀서 풀 수 없는 구조

1. 단일 책임 원칙- '클래스가 담당하는 책임은 하나로 제한해야 한다'는 설계 원칙  [문제 코드]DiscountManager 클래스가 Product클래스 대신 값을 확인하는 행위->  DiscountManager는 다른 클래스에게 책임을 지우지 않고 무엇이든 대신 해주는, 즉 과보호하는 부모 class DiscountManager{ List discountProducts; int totalPrice; //상품 추가 메서드 boolean add(Product product, ProductDiscount productDiscount){ ... } //할인 가격 확인 메서드 static int getDiscountPrice(int pr..

[내 코드가 그렇게 이상한가요?] 7장-컬렉션:중첩을 제거하는 구조화 테크닉

1. 이미 존재하는 기능을 다시 구현하지 말기  개선 전) 중첩 코드 존재(for문 안에 if절)boolean hasPrisonKey = false;//items는 List 자료형for(Item each : items){ if(each.name.equals("감옥 열쇠")){ hasPrisonKey = true; break; }}  개선 후) 컬렉션 사용(anyMatch)boolean hasPrisonKey = items.stream().anyMatch( item -> item.name.equals("감옥 열쇠"));   이처럼 anyMatch 메서드를 알고 있으면, 복잡한 로직을 직접 구현하지 않아도 됩니다. 반대로 모르면 로직을 직접 구현해야 하므로, 코드가 쓸데없이 복잡해집..

[내 코드가 그렇게 이상한가요?] 6장-조건 분기 : 미궁처럼 복잡한 분기 처리를 무너뜨리는 방법

1. 조건 분기가 중첩되어 낮아지는 가독성 [문제]//살아 있는가if(0    여러 개의 조건을 판정하기 위해서 if 조건문 내부에 if 조건문, 그리고 내부에 또 if 조건문을 넣는 식으로 if 조건문을 중첩했습니다. 어떤 조건을 만족할 때 어떤 로직이 처리되는지 이해하는 것만으로도 많은 시간을 낭비합니다.     [해결] 1) 조기 리턴으로 중첩 제거하기 조기 리턴은 조건을 만족하지 않는 경우 곧바로 리턴하는 방법입니다.//조건 로직if(member.hitPoint    조기 리턴의 장점은 중첩이 제거되어 가독성이 좋아졌습니다. 또 다른 장점은 바로 조건 로직과 실행 로직을 분리할 수 있다는 것입니다.   예를 들어 아래와 같은 로직 추가 되었다고 합시다.멤버가 테크니컬포인트(TP)를 가짐 - 조건 ..

[내 코드가 그렇게 이상한가요?] 5장 응집도:흩어져 있는 것들

응집도란? 모듈 내부에 있는 데이터와 로직 사이의 관계가 얼마나 강한지 나타내는 지표입니다.(모듈을 클래스라고 생각하기) 응집도가 높은 구조는 변경하기 쉬우며, 바람직한 구조입니다. 반대로 응집도가 낮은 구조는 변경 시 문제가 발생하기 쉽습니다.      응집도를 낮추는 경우  1. static 메서드 오용static 메서드를 사용하는 이유는 객체 지향 언어를 사용할 때, C 언어 같은 절차 지향 언어의 접근 방법을 사용하려 하기 때문입니다. 절차 지향 언어에서는 데이터와 로직이 따로 존재하도록 설계합니다. 이러한 접근 방법을 객체 지향 언어에 적용하여 설계하면, 데이터와 로직을 별도의 클래스에 배치하게 됩니다. 그래서 클래스의 인스턴스를 생성하지 않고도 사용할 수 있는 static 메서드를 활용하는 것..