[새배내] 자동차 경주 미션을 하며 새로 배운 내용

Junseo Kim·2021년 2월 10일
1

2021.02.03 ~ 2021.02.15


default package import

다른 패키지에서 default 패키지를 import 할 수 없다.
-> default 패키지 사용 지양

static 클래스의 생성자

인스턴스를 생성할 필요가 없는 클래스의 생성자는 private으로 선언해주어 인스턴스 생성을 못하게 막는 것이 좋다. static 메소드만 존재하는 클래스가 이런 경우이다. 클래스명.메소드명으로 호출할 수 있기 때문에 인스턴스를 생성할 필요가 없다.

인스턴스 필드와 클래스 필드 유효기간

인스턴스 변수는 인스턴스의 생성 ~ 소멸
클래스 변수는 JVM이 클래스 load ~ 클래스 unload
- 클래스 load: 클래스가 사용되는 시점에 클래스의 바이트코드를 읽어서 메모리에 할당
- 클래스 unload: 클래스가 더 이상 사용되지 않을 때 메모리에서 해제

효과적인 이름 짓기

참고: 효과적인 이름짓기

의미있는 공백 라인

공백 라인을 나눌 때 문맥이 분리되는 경우에만 사용한다. 문맥별로 나누다 보면 메소드 추출로 이어질수도 있다. 의미없이 공백 라인을 사용하면 안된다.

변수 이름에 자료형 사용하지 않기

List<Car> carList; 등 변수이름에 List 같은 자료형이 들어가지 않게 하기

final 사용

다른 언어와 달리 java는 기본적으로 불변이 아니다. 값이 변하지 않는 경우는 final을 명시적으로 붙여줘서 불변으로 만들어주는 것이 좋다.

테스트만을 위한 코드 구현하지 않기

구현 코드에 테스트를 하기 위한 새로운 메소드는 만들지 마라. 생성자는 예외.

MVC

domain(model): 핵심 비지니스 로직 객체
view: UI 관련 객체
controller: domain과 veiw를 연결

view는 domain에 의존 but domain은 view에 의존 x

getter 반환 타입

일반적으로 getter는 객체 내부 변수와 같은 타입을 반환. 아래의 예제로 보면 바로 String으로 값을 꺼낸다면, 1)Car객체의 Racer를 꺼내야하는 경우나 2)다른 사람이 내 코드를 읽을 때 의미가 모호해 질 수 있다.

public class Car {
    private Racer racer;
    
    // 객체 내부 변수와 같은 타입
    public Racer getRacer() {
        return racer;
    }
    
    // 객체 내부 변수와 다른 타입
    /*
    public String getRacer() {
        return racer.getName();
    }
    */
}

객체에 메세지 전달

getter를 통해 값을 꺼내오기보다는 객체에 메세지를 보내서 처리하기


// 잘못된 경우
if (this.position.getPosition() == car.position.getPosition()) {

}

// 올바른 경우
if(this.position.isSame(car.position)) {

}

Pattern.compile

Pattern.compile은 비용이 많이 든다. 미리 만들어 놓고 사용하기

디미터 법칙

한 줄에 점을 하나만 찍기(무조건 적인 것은 아니다. 예를 들어 stream()). 다른 객체 내부에서 또 다른 객체를 알아내는 식으로 해서는 안된다. 이런식으로 코딩되어 있다면 메소드 체이닝 중간에 값의 타입이 바뀐다거나 하는 경우에 연결된 모든 클래스를 수정해야 할 수 있다. 즉 변화에 유연하게 대처하지 못하게 된다.

equals

name.equals(EMPTY)EMPTY.equals(name)의 차이는?
name이 만약 null로 들어온다면 name.equals(EMPTY)에서는 NullPointerException이 발생할 것이다. 하지만 EMPTY.equals(name)에서는 equals에서 null을 처리하기 때문에 Exception이 발생하지 않는다.

boolean 반환 메소드

boolean 반환 메소드의 메소드명은 isXXXcanXXX

getter, setter, toString

이런 기본적인 메소드는 클래스 가장 하단에 위치하게 하는 것이 일반적이다.

private

클래스 내부에서만 사용하는 메소드는 private을 붙여준다. 코드 작성시 일단 접근제어자를 private으로 시작한 이후 필요시 접근제어자를 변경하는 습관.

원시값 포장시의 이점

  • 심리적 안정: 포장한 객체에서 검증 작업을 거칠 수 있기 때문에 포장된 변수는 이름 검증이 끝난 변수
  • 책임 분리: 원시값을 포장하면서 포장한 객체에서 가져야하는 책임을 옮길 수 있다.
  • 테스트 용이

일급컬렉션

  • 컬렉션 조작을 내부에서만 하도록 할 수 있다.(외부에서 조작할 수 없게)
List<Car> cars;
cars.add(); // 가능
Cars cars;
cars.add(); // Cars에 add라는 메소드가 있으면 가능 없으면 조작 불가
  • 꼭 불변이 아니어도 상관없다.
  • 생성자의 매개변수로 콜렉션을 받는다.

참고: 일급 컬렉션 (First Class Collection)의 소개와 써야할 이유

정적 팩토리 메소드

클래스 메소드인데 객체의 생성을 담당하는 역할을 한다. 즉, 직접적으로 생성자를 통해 생성을 하는 것이 아니라 메소드를 통해 객체를 생성한다.

생성자가 존재하는데 왜 이렇게 메소드를 사용해서 객체를 생성할까?

  1. 생성 목적에 따라 이름을 달리 줄 수 있다.
  2. 캐싱을 통해 호출 때 마다 매번 새로운 객체를 생성할 필요가 없어진다.
  3. 상속 구조인 경우 조건에 따라 하위 객체를 생성해 줄 수 있다.
  4. 객체 생성을 캡슐화 할 수 있다.

참고:

Optional

Optional 공부 후 정리해놓은 것

전략패턴

전략패턴 공부 후 정리해놓은 것

불변객체

불변객체 공부 후 정리해놓은 것

방어적복사

방어적복사 공부 후 정리해놓은 것

인텔리제이 단축키

자주 쓰는 단축키 정리

0개의 댓글