본문 바로가기
반응형

전체 글113

finalizer와 cleaner 사용을 피하라 finalizer와 cleaner 사용을 피하라 자바의 객체 소멸자 1. finalizer (자바 8까지) 예측 불가능하고, 상황에 따라 위험할 수도 있어 일반적으로 불필요 2. cleaner (자바 9~) finalizer보다는 덜 위험하지만 마찬가지로 예측 불가능, 느림, 일반적으로 불필요하다. 어째서 불필요한지? 1. finalizer와 cleaner는 즉시 수행된다는 보장이 없다. 즉, 두 가지로는 제때 실행되어야 하는 작업은 절대할 수 없다. ex) 파일 닫기의 경우, 동시에 열 수 있는 파일 개수에 한계가 있기 때문에, finalizer나 cleaner가 제 때 실행되지 않는다면, 새로운 파일을 열지 못하게 될 수 있다. 2. 수행 여부를 보장하지 않는다. 접근할 수 없는 일부 객체에 딸린 종.. 2022. 3. 22.
상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다. 재정의 가능 메서드를 호출할 수 있는 모든 상황을 문서로 남겨야한다. 메서드 설명을 작성하기위해 @implSpec 태그를 붙여주면 자바독 도구가 생성해준다. 다음은 java.util.AbstractCollection에서 찾은 예 위와 같이 메서드 설명을 통해서 내부 동작 방식을 알 수 있다. 이렇게 작성하는 것은 상속이 캡슐화를 해치기 때문이다. 클래스를 안전하게 상속할 수 있도록 하려면 내부 구현 방식을 설명해야만 한다. 문서를 남기는 것 뿐만 아니라 상속을 위해 훅(hook)을 잘 선별하여 protected 메서드 형태로 공개해야 할 수도 .. 2022. 3. 15.
스트림 병렬화는 주의해서 적용하라 자바 8부터 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원한다. 이 병렬 실행을 올바르게 사용하는 방법을 알아보자. import static java.math.BigInteger.ONE; import static java.math.BigInteger.TWO; import java.math.BigInteger; import java.util.stream.Stream; // 스트림을 사용해 처음 20개의 메르센 소수를 생성하는 프로그램 public class Main { public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .filter(m.. 2022. 3. 12.
람다보다는 메서드 참조를 사용하라 람다보다는 메서드 참조를 사용하라 람다는 익명 클래스보다 간결하다. 간결한 람다를 더 간결하게 만드는 방법이 메서드 참조이다. 메서드 참조를 써야하는 경우 1. 대부분의 경우 2. 람다로 구현했을 때 너무 길거나 복잡한 경우 3. 기능을 잘 드러내는 이름을 사용하고 싶을 때 lottoNumbers.stream() .map(lottoNumber -> new LottoTicket(lottoNumber)) .collect(Collectors.toList()) 위와 같은 코드를 메서드 참조로 바꾸면 다음과 같다. lottoNumbers.stream() .map(LottoTicket::new) .collect(Collectors.toList()) 위와 같이 메서드 참조를 사용하면 똑같은 결과를 더 보기 좋게 얻을.. 2022. 3. 7.
equals는 일반 규약을 지켜 재정의하라 equals를 재정의할 때 곳곳에 함정이 존재하므로 주의해야 한다. 다음과 같은 상황들에서는 equals를 재정의하지 않아야 한다. equals를 재정의하지 않는 것은 인스턴스는 오직 자기 자신과만 같다는 것이다. 재정의 하지 말아야 할 때 1. 각 인스턴스가 본질적으로 고유할 때 값을 표현하는 게 아니라 동작하는 개체를 표현하는 클래스에서는 재정의를 하지 않는다. 예를 들어 controller, view 등등 이미 Object에 equals 메서드가 잘 구현되어있다. // Object의 equals 메소드 public boolean equals(Object obj) { return (this == obj); }2. 인스턴스의 '논리적 동치성'을 검사할 일이 없다. 3. 상위 클래스에서 재.. 2022. 3. 2.
값 객체(VO) 자동차 경주 미션 중 다른 크루들이 값 객체를 사용하여 구현하는 것을 보았다. 값 객체를 알고 있었지만 사용하지 못한 부분에 대해 반성을 하면서 작성하는 반성문 도메인 주도 설계 철저 입문 책을 보고 정리하는 글입니다. 값 객체란? 시스템 특유의 값을 표현하기 위해 정의하는 객체 값의 성질 1. 변하지 않는다. 2. 주고받을 수 있다. 3. 등가성을 비교할 수 있다. 값 객체는 값의 성질을 가지고 있다. 1. 값은 변하지 않는다. 값은 변화하지 않는다. 우리가 값을 수정할 때는 새로운 값을 대입한다. 예를 들면, String greet = "하이" greet = "안녕" greet의 값이 처음에는 "하이" 였지만 "안녕"으로 수정되었다. 그렇지만 이것을 값이 변화했다고 보지 않는다. 값은 "하이", "안.. 2022. 2. 20.
[자동차 경주 미션] 전략 패턴 사용 후기 자동차 경주 미션 과정 진행 중에 전략 패턴을 사용해보고 작성하는 글 Car 객체가 조건을 만족할 시 움직이는 기능을 구현하기 위해서 레벨 1단계에서는 다음과 같이 구현을 하였다. public void move(int number) { if (number >= MOVING_CONDITION_NUMBER) { position += 1; } } 이 메서드에 대한 테스트는 다음과 같다. @Test public void 전진_여부() { Car testCar = new Car("아스피", 2); testCar.move(4); assertThat(testCar.isSamePosition(new Car("배카라", 3))).isEqualTo(true); } 위와 같이 move라는 메서드에 직접 값을 삽입하여 전진 .. 2022. 2. 18.
[자동차 경주 미션] 피드백 반영 1. Car 생성자 수정 1차 완성한 코드에는 다음과 같이 Car 클래스에 2개의 생성자를 작성하였다. position을 초기화하는 생성자는 프로덕션 코드에서는 사실 필요없었지만 테스트를 위해서 추가한 코드였다. 그래서 위와 같은 피드백을 받게 되었다. 테스트만을 위한 코드를 프로덕션 코드에 만드는 것이 괜찮을까? 라는 의구심이 있었는데 닉께서 피드백으로 확실하게 정리해주었다. 기존에는 필드 변수 position을 미리 0으로 선언할 때 초기화하였지만 추천해주신 방법으로 다음과 같이 생성자를 만들어 두 생성자를 모두 의미있게 사용할 수 있었다. 이 방법을 알고는 있었지만 생각해내지 못한 방법이라 더 깊이 생각하지 못한 점에 대해 반성을 하였다. 아직 노오력이 부족하다. 이 방법을 통해 position을 .. 2022. 2. 13.
페어 프로그래밍 오늘 페어 프로그래밍을 통해 자동차 경주 게임 미션을 완료하였다. 프리코스와는 다르게 단위 테스트를 제작하여 미션을 수행해야 했다. 페어와 나, 둘 다 단위 테스트에 대해 무지해서 쉽지 않았다. 이는 앞으로 더 공부를 해 볼 예정이다. 페어 프로그래밍을 진행해보고 느낀 점 새로운 사람과 가까워지는 것이 제일 큰 장점이다. 페어 프로그래밍을 하면서 막히는 부분들과 의견 차이를 해결하면서 페어에게 조금씩 의지하게 되었다. 그래서 내적 친밀도가 조금 올라간 것 같은 느낌이 든다. 그런데 비대면이기 때문에 줌 안에서는 어색함이 많이 사라졌지만, 막상 현실에서 만나면 아,,아안녕하세요,, 내 의견이 옳다 라는 생각을 많이 굽히게 되었다. 페어 프로그래밍을 하면서 내 의견이 옳다 라는 생각을 많이 한다는 것을 깨달.. 2022. 2. 11.
반응형