우테코 1주차 학습 - 클린 코드

찬디·2025년 2월 16일

우테코

목록 보기
2/18

응집도 키우기

한 Position을 여러곳에서 사용하는 경우 버그가 생길 가능성이 높아진다.
(여기저기서 채용하기 때문에)

X

            public void increase() {
                value++;
            }

O

			public Position increase() {
                return new Position(value + 1);
            }

고민할거리
무조건 객체를 새로 생성해 리턴하는게 항상 좋을까?
위 코드의 문제점은 성능 문제가 있음.

성능 문제 해결 (캐싱)

객체를 항상 생성해서 리턴한다는 것은 메모리 사용량이 크다는 것을 의미한다.

  • Map 캐싱을 적용한다
record Car(
                String name,
                Position position
        ) {
            private static final Map<String, Car> CACHE = new ConcurrentHashMap<>();

            public static Car of(final String name, final Position position) {
                return CACHE.computeIfAbsent(toKey(name, position), key -> new Car(key, position));
            }

            private static String toKey(final String name, final Position position) {
                return name + position.value();
            }

            public Car forward() {
                // Note: 움직일 때 마다 캐싱된 객체가 재활용된다. 하지만 캐싱된 객체가 많을수록 메모리 사용량이 증가한다.
                return Car.of(name, position.increase());
            }
        }

of(정적 팩토링방식), computIfAbsent등 다음에 써보자

캐싱의 범위가 넓으면?

  • 자주 사용되는 것만 사용하자
 private static final int CACHE_MIN = 0;
 private static final int CACHE_MAX = 5;

...
 if (CACHE_MIN <= value && value <= CACHE_MAX) {
                    return CACHE.get(value);
                }
return new PositionForEnhancedCache(value);

캐싱을 무조건 하는게 좋을까?

  • JVM이 알아서 해주는게 성능 나을때도 있음.
  • 보다시피 성능 개선이 크게 필요한게 아니면 복잡한 코드만 작성하게 될수도 있음.
    • 성능 문제를 개선해야하는 요구사항이 생기면 고려하자

적절하게 불변객체와 가변 객체 방식을 섞어서 사용하기

            public void forward() {
                position = position.increase();
            }
            가변객체 방식처럼 increase를 사용하는 모습
public Position increase() {
	return new Position(value + 1);
}

위 방식을 다음 미션에 한번 적용해보자.

객체 상태 변경가능함 문제

List<Car> getParticipants() {
                // Note: 매번 새로운 리스트를 생성하여 성능상의 이슈가 발생할 수 있다.
                return participants;
            }

위 코드에서 List를 반환하면 외부에서 이를 수정해버릴 수 있다.

해결방법

 List<Car> getParticipants() {
	// Note: 매번 새로운 리스트를 생성하여 성능상의 이슈가 발생할 수 있다.
    (방어적 복사)
	return new ArrayList<>(participants);
}

해결방법2

프로퍼티를 오픈하지 않고 단지 메시지만 받아 내부에서 처리하기
getParticipants 제거 및 add 등 함수단위로 관리하기

불변 컬렉션, 방어적 복사 적절히 사용하기

  • 방어적 복사 - 성능문제 발생
  • 불변 컬렉션 - 원본 컬렉션가지고있으면 여전히 수정가능
    • 이 부분 몰랐는데 주의할 것
      입력받을때 - 방어적 복사
      응답할때 - 불변 컬렉션으로 반환
profile
깃허브에서 velog로 블로그를 이전했습니다.

0개의 댓글