3개월차 신입 비전공 개발자가 읽기 좋은 코드를 만들어보고자 공부하는 내용입니다. 부족하거나 새롭게 공부해보면 좋을 것 같은 추천, 글에서 발견된 문제에 대한 이야기는 언제든 환영합니다!
public enum weightEnum {
KG,
G;
double getConversionRate(weightEnum unit) {
if (this == unit) {
return 1; //같은 단위
}
if (this == KG && unit == G) {
return 1000; //1kg 당 g
} else {
return 0.001; //1g 당 kg
}
}
}
getConversionRate
에서 return 되는 수들은 매직 넘버가 됨public enum weightEnum {
KG,
G;
static final int SAME_CONVERSION_RATE = 1;
static final int KG_IN_G = 1000;
static final double G_IN_KG = 0.001;
double getConversionRate(weightEnum unit) {
if (this == unit) {
return SAME_CONVERSION_RATE;
}
if (this == KG && unit == G) {
return KG_IN_G;
} else {
return G_IN_KG;
}
}
}
public class FuelSystem {
List<Double> tanks = new ArrayList<>();
int getAverageTankFillingPercent() {
double sum = 0;
for (double tankFilling : tanks) {
sum += tankFilling;
}
double averageFuel = sum/tanks.size();
//백분율로 반올림
return Math.toIntExact(Math.round(averageFuel*100));
}
}
int getAverageTankFillingPercent() {
double sum = 0;
for (double tankFilling : tanks) {
sum += tankFilling;
}
double averageFuel = sum/tanks.size();
int roundedToPercent = Math.toIntExact(Math.round(averageFuel*100));
return roundedToPercent;
}
int getAverageTankFillingPercent() {
double sum = 0;
for (double tankFilling : tanks) {
sum += tankFilling;
}
double averageFuel = sum/tanks.size();
return roundToIntegerPercent(averageFuel);
}
static int roundToIntegerPercent(double value) {
return Math.toIntExact(Math.round(value*100));
}
getAverageTankFillingPercent()
메소드에 직접 로직을 수행하는 코드를 쓰지 않아도 됨 → 메소드가 짧아짐. 각각의 메소드가 짧아지니 코드를 이해하기 쉬워짐getAverageTankFillingPercent()
가 하위 메소드 roundToIntegerPercent()
를 호출 → 상위 메소드의 이해도 개선public class Inventory {
private List<Supply> list = new ArrayList<>();
void add(Supply supply) {
list.add(supply);
Collections.sort(list);
}
boolean isInStock() {
//빠른 구현
return Collections.binarySearch(list, new Supply(name)) != -1;
}
}
//빠른 구현
이라는 코드가 binarySearch의 사용 이유를 설명해주지 않고 있음public class Inventory {
// 리스트를 정렬된 채로 유지한다. isInStock()을 참고 한다.
private List<Supply> list = new ArrayList<>();
void add(Supply supply) {
list.add(supply);
Collections.sort(list);
}
boolean isInStock() {
/*
* 재고가 남았는지 재고명으로 확인해야 한다면,
* 재고가 1000개 이상일 때 심각한 성능 이슈에 직면한다.
* 1초안에 항목을 추출하기 위해
* 비록 재고를 정렬된 채로 유지해야 하지만
* 이진 검색 알고리즘을 사용하기로 결정했다.
*/
return Collections.binarySearch(list, new Supply(name)) != -1;
}
}
public class Supply {
/*
* 아래 코드는 어디서든 재고를 식별한다
*
* S로 시작해 숫자 다섯자리 재고 번호가 나오고
* 뒤이어 앞의 재고 번호와 구분하기 위한 역 슬래시가 나오고
* 국가 코드가 나오는 엄격한 형식을 따른다.
* 국가 코드는 반드시 참여 국가인 (US, EU, RU, CN) 중
* 하나를 뜻하는 대문자 두 개여야 한다.
* 이어서 마침표와 실제 재고명이 소문자로 나온다.
* */
static final Pattern CODE = Pattern.compile("^S\\d{5}\\\\(US|EU|RU|CN)\\.[a-z]+$");
}
public class Supply {
/*
* 아래 코드는 어디서든 재고를 식별한다
*
* 형식 : "S<inventory-number>\<COUNTRY-CODE>.<name>"
* 유요한 예 : "S12345\US.pasta", "S08321\CN.wrench"
*
* 유효하지 않은 예:
* "R12345\RU.fuel" : (재고가 아닌 자원)
* "S1234\US.light" : (숫자가 5개여야 함)
* "S01234\KO.coconut" : (잘못된 국가 코드. US, EU, RU, CN 중 하나를 사용해야 함)
* "S88888\EU.coffee " : (마지막에 여백이 있음)
* */
static final Pattern SUPPLY_CODE = Pattern.compile("^S\\d{5}\\\\(US|EU|RU|CN)\\.[a-z]+$");
}