본문 바로가기

Language

(33)
Effective JAVA - Item19 : 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라. 결론 상속을 해서 확장을 했을 때 많은 문제를 일으킨다. 해결 방법은 클래스 상속시 상속을 위해 설계하고 설명해주는 문서를 만드는 것이다. 그렇게 만든 클래스가 아니라면 해당 클래스의 상속을 금지시켜라 상속이 위험한 이유 내가 어떤 클래스를 상속해서 클래스를 만든다고 가정하자. 하지만, 그 상위 클래스는 내가 수정할 수 있는 나의 코드가 아닌 다른 패키지의 클래스를 사용한다면 내가 통제를 할 수가 없다. 따라서, 다음 릴리즈 등에서 변경시 내가 할 수 있는 것이 없다. 따라서 코드 수정, 안정성 면에서 다소 위험하다. 상속을 할 수 있게 하는 방법 : 상속을 위한 설계와 API 문서 작성 1. 메서드를 재정의하면 메서드 내부가 어떻게 동작하는지 상세히 정리하여 문서로 남겨야 한다. -> 어떤 순서로 호출..
Effective JAVA - Item18 : 상속보다는 컴포지션을 사용하라. 주제 "다른 패키지의 구체 클래스를 상속하는 것은 위험 하다." 문제점 // 문제점 : 메서드 호출과 달리 상속은 캡슐화를 깨뜨린다. // = 상위 클래스가 어떻게 구현되는냐에 따라 하위 클래스의 동작에 이상이 생길 수 있다. // = 상위 클래스는 릴리스마다 내부 구현이 변경될 수 있고 이에 따라 하위 클래스가 동작하지 않을 수 있다. // 상위 클래스의 메서드를 재정의하는 것은 내부 모든 동작을 파악하기도 어렵고 문서에 적혀있지 않은 경우도 존재한다 // 또한, 새로운 릴리스에서 내부 변경시 이에 맞추어 모두 수정해야 하기에 유연하지 못한다. 해결 // 해결책 : 컴포지션 // 방법 // 1. 기존의 클래스를 확장하는 대신, 새로운 클래스를 만들고 private 필드로 기존 클래스의 인스턴스를 참조하..
Effective JAVA - Item17 : 변경 가능성을 최소화하라. 1. 불변 클래스 // - 정의 : 그 인스턴스의 내부 값을 수정할 수 없는 클래스 // - 객체가 파괴되는 순간까지 내부 정보는 절대 변경되지 않는다. // - 예시 : String, 기본 타입의 박싱된 클래스들, BigInteger, BigDecimal // - 불변클래스로 만드는 이유 : 설계, 구현, 사용이 쉬우며 오류가 생길 여지도 적고 안전하다. 2. 불변 클래스를 만드는 5가지 규칙 // - 1. 객체의 상태를 변경하는 메서드(변경자, setter)를 제공하지 않는다. // - 2. 클래스를 확장할 수 없도록 한다. // -> 하위클래스에서 악의적으로 변경을 막고 상속을 막는 방법은 final로 선언하는 방법이 있다. // - 3. 모든 필드를 final로 설정한다. // - 4. 모든 필드..
Effective JAVA - Item16 : public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라. // 1. public 클래스라면 private 멤버와 각 멤버의 접근자(getter/setter)를 제공하는 것이 맞음 // 2. package-private 클래스나 private 중첩클래스(클래스 내부 클래스)는 데이터 필드 public 가능 // - 다만, 그 클래스가 표현하려고 하는 추상 개념은 올바르게 표현해야 함. // - 클래스 선언, 클라이언트 코드 등 훨씬 깔끔하다. // - "package 내부에서만 사용하는 클래스라면 웬만하면 package-private로 사용하자" // 3. 클래스의 public 필드가 불변이라도 public 선언은 좋은 방법은 아니다. // 결론 : public 클래스는 절대 가변 필드 노출 x, 불변 필드라면 노출을 생각해볼 수 있지만 안전하진 않다. // p..
Effective JAVA - Item15 : 클래스와 멤버의 접근 권한을 최소화하라. 1. 잘 설계된 컴포넌트 // - 컴포넌트 : 클래스와 객체 // - 클래스의 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 잘 숨긴 구조 // - 오직 API를 통해서만 다른 컴포넌트와 교류하는 구조 // - 정보 은닉(캡슐화)의 근간 2. 정보 은닉의 장점 // 공통 : 시스템을 구성하는 컴포넌트들을 독립시켜 개발, 테스트, 최적화, 적용, 분석, 수정 등을 개별적으로 가능하게 만든다. // 1. 시스템 개발 속도를 높인다. // 2. 시스템 관리 비용을 낮춘다. // 3. 성능 최적화에 도움을 준다. // 4. 소프트웨어 재사용성을 높인다. // 5. 큰 시스템을 제작하는 난이도를 낮춰준다. 3. 자바의 정보 은닉 // - 접근 제어 매커니즘 : 클래스, 인터페이스, 멤버의 접근성을 접근 제어..
Effective JAVA - Item14 : Comparable을 구현할지 고려하라. Comparable의 유일무이한 메서드인 compareTo 메서드 1. equals 메서드와 다른점 // - Object의 메서드가 아니라 Comparable의 메서드이다. // - 단순 동치성 비교에 더해 순서까지 비교할 수 있으며 제네릭하다. // (Comparable을 구현했다는 것은 클래스의 인스턴스들에 자연적인 순서가 존재함을 의미한다.) // - 따라서, 정렬이 가능하다. // - 검색, 극단값 계산, 자동 정렬되는 컬렉션관리 가능 // (TreeSet, TreeMap, Collections, Array) // "알파벳, 숫자 등과 같이 순서가 명확한 값 클래스를 작성한다면 반드시 Comparable 인터페이스를 구현하자" 2. compareTo의 일반 규약 // - 이 객체와 주어진 객체의 ..
Effective JAVA - Item13 : clone 재정의는 주의해서 진행하라 1. 배경 // Cloneable는 복제해도 되는 클래스임을 명시하는 인터페이스 // clone메서드는 해당 인터페이스가 아닌 Object에 protected로 선언되어 있음. // 따라서, Cloneable을 구현하는 것만으로는 clone메서드를 호출할 수 없다. 2. Cloneable 인터페이스의 역할 // - 기본적으로 해당 인터페이스는 Object의 protected 메서드인 clone의 동작 방식을 결정한다. // - 해당 인터페이스를 구현하고 object의 clone메서드를 재정의해 호출시 해당 클래스의 필드를 복사한 객체 반환 // - 해당 인터페으스를 구현안하고 clone 메서드 사용시 CloneNotSupportedException 발생 3. Clone메서드의 기본적인 구현 방법 // -..
Effective JAVA - Item12 : toString을 항상 재정의하라. 1. 주제 "toString을 잘 구현한 클래스는 사용하기에 훨씬 즐겁고, 그 클래스를 사용한 시스템은 디버깅이 쉽다" 2. toString의 일반 규약 // 1. "간결하면서도 사람이 읽기 쉬운 형태의 유익한 정보" // 2. "모든 하위클래스에서 해당 메서드를 재정의하라" 3. toString 메서드가 자동 호출되는 경우 // 1. println, printf // - 아래의 경우에서 인스턴스 출력시 자동으로 toString이 호출됨을 확인할 수 있다. PhoneNumber number1 = new PhoneNumber(111, 222, 333); System.out.println(number1); // 2. 문자열 연결 연산자(+) String now = "hello"; System.out.prin..