Search
Duplicate
🚀

1단계 - 문자열 덧셈 계산기

1. 객체지향 생활 체조 원칙 - 규칙 3

모든 원시값과 문자열을 포장한다. 적극 사용하자.
만일 Item이라는 클래스에 최소가격 1000원이상의 price라는 아이템의 가격 정보를 필드로 가지고 있다면 이를 포장(boxing)하여 사용할 수 있다.
class Item{ private int price; }
Java
복사
기존의 클래스
class ItemPrice{ private final int price; ... } class Item{ private ItemPrice price; }
Java
복사
ItemClass로 래핑한 클래스
그렇다면 어째서 이렇게 번거롭게 래핑을 해줘야 할까? 그 이유는 OOP의 개념을 생각해봐야한다.
객체지향 프로그래밍(OOP: Object-Oriented Programming) : 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 객체들의 모임으로 파악하고자 하는 것으로 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다. - 위키백과 (객체 지향 프로그래밍)
여기서 중요한점은 메세지를 주고받는다는 것인데, 이 개념이 객체간의 결합도를 떨어트리는 중요한 역할이다. 객체가 가지고있는 원시값 필드정보를 다른 객체에서 마음대로 꺼내서 쓸 수 있다면
해당 객체들간에 의존성이 생기게되고, 이는 추후 기능추가및 유지보수의 난이도를 높힐 수 있다.
또한, price라는 가격의 제약조건을 item이 아닌 price자체가 책임지게 되면서 가격에 대한 유효성 검증도 ItemPrice라는 래핑객체에서 수행하면 된다.
객체가 너무 많이 만들어지는게 아닌가 싶지만, 그것은 문제가 아니다.
문제는 여러 객체들간의 의존성이 얽혀 고치지 못하는 스파게티 코드가 되는 것이다.

2. 추상화 수준에 맞는 예외를 던져라

메소드가 저 수준 예외를 처리하지않고 throw 해버리면 상위 메소드에서 종종 의도치 않은 예외가 튀어나오게 되는데, 이는 내부 구현방식을 상위에 노출시켜 상위 API를 오염시킬 수 있고, 릴리즈에서 다른 예외가 튀어나와 기존 클라이언트 프로그램을 깨지게 할 수도 있습니다.
상위 메소드에서 저수준 예외를 번역해야한다.
저수준 예외의 내용이 필요하다면 예외 연쇄를 사용하라.
예외 번역을 남용하지 말자.

3. Pattern 인스턴스는 재활용하자.

Pattern 인스턴스는 한 번 컴파일 후 재사용할 것을 권장.
Pattern.compile 내부 구현
: 매번 인스턴스 생성
// Pattern public static Pattern compile(String regex) { return new Pattern(regex, 0); }
Java
복사
compile호출시마다 Pattern 인스턴스를 생성하기 때문에 한 번 쓰고 버리고 또 compile하는것은 비용낭비이다. 그렇기에 JavaDoc에서도 재사용할 것을 권장합니다.
If a pattern is to be used multiple times, compiling it once and reusing it will be more efficient than invoking this method each time

4. null을 반환하지말아라. 빈객체 혹은 예외를 반환하라.

null을 반환하는것은 메소드를 호출하여 반환값을 기대하는 로직에서 매번 null check를 해줘야 하는데, null 처리를 놓치게되면 NPE가 발생 할 확률이 높습니다.
그에 대한 대책으로 Java 8 에서는 Optional이 나왔으며 이를통해 빈객체 혹은 예외를 반환하도록 합시다.
public int testMethod(){ return Optional.of(value).orElse(0); //return Optional.of(value).orElseThrow(IllegalArgumentException::new); //Exception }
Java
복사

5. String.matches 보다는 Pattern을 활용하자.

String.matches의 내부 구현을 보면 아래와 같다.
// String.matches public boolean matches(String regex) { return Pattern.matches(regex, this); } // Pattern public static boolean matches(String regex, CharSequence input) { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(input); return m.matches(); }
Java
복사
결국, Pattern을 컴파일하고있는데, 차라리 Pattern을 compile한 이후 재활용할 수 있도록 하자.

6. 변수 명에 타입,자료형(String, int...) 사용은 지양하자.

변수 명에 자료형을 쓰지 않아도 타입을 통해 충분히 어떤 변수인지 파악이 가능하도록 네이밍을 하자.