아이템 18 : 상속보다는 컴포지션을 사용하라 상속은 코드를 재사용하는 강력한 수단이지만, 항상 최선은 아니다. 잘못 사용하면 오류를 내기 쉬운 소프트웨어를 만들게 된다. 메서드 호출과 달리 상속은 캡슐화를 깨뜨린다. 다르게 말하면, 상위 클래스가 어떻게 구현되느냐에 따라 하위 클래스의 동작에 이상이 생길 수 있다. 기존 클래스를 확장하는 대신, 새로운 클래스를 만들고 private 필드로 기존 클래스의 인스턴스를 참조하게 하자. 기존 클래스가 새로운 클래스의 구성요소로 쓰인다는 뜻에서 이러한 설계를 컴포지션 구성이라 한다. 새 클래스의 인스턴스 메서드들은 기존 클래스의 대응하는 메서드를 호출해 그 결과를 반환한다. 이 방식을 전달이라 하며, 새 클래스의 메서드들을 전달 메서드라 부른다. 그 결과 새로운..
아이템 17 : 변경 가능성을 최소화하라 불변 클래스란 간단히 말해 그 인스턴스의 내부 값을 수정할 수 없는 클래스다. 클래스를 불변으로 만들려면 다음 다섯 가지 규칙을 따르면 된다. 객체의 상태를 변경하는 메서드를 제공하지 않는다. 클래스를 확장할 수 없도록 한다. 모든 필드를 final로 선언한다. 모든 필드를 private으로 선언한다. 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다. 불변 객체는 단순하다. 불변 객체는 생성된 시점의 상태를 파괴될 때까지 그대로 간직한다. 또한 불변 객체는 근복적으로 스레드 안전하여 따로 동기화할 필요가 없다. 불변 객체에 대해서는 그 어떤 스레드도 다른 스레드에 영향을 줄 수 없으니 불변 객체는 안심하고 공유할 수 있다. 불변 객체는 자유롭게 공유할 ..
아이템 16 : public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 패키지 바깥에서 접근할 수 있는 클래스라면 접근자를 제공함으로써 클래스 내부 표현 방식을 언제든 바꿀 수 있는 유연성을 얻을 수 있다. public 클래스가 필드를 공개하면 이를 사용하는 클라이언트가 생겨날 것이므로 내부 표현 방식을 마음대로 바꿀 수 없게 된다. package-private 클래스 혹은 pirvate 중첩 클래스라면 데이터 필드를 노출한다 해도 하등의 문제가 없다. 그 클래스가 표현하려는 추상 개념만 올바르게 표현해주면 된다. 핵심 정리 public 클래스는 절대 가변 필드를 직접 노출해서는 안 된다. 불변 필드라면 노출해도 덜 위험하지만 완전히 안심할 수는 없다. 하지만 package-priva..
아이템 15 : 클래스와 멤버의 접근 권한을 최소화하라 정보 은닉의 장점은 정말 많다. 그중 대부분은 시스템을 구성하는 컴포넌트들을 서로 독립시켜서 개발, 테스트, 최적화, 적용, 분석, 수정을 개별적으로 할 수 있게 해주는 것과 연관되어 있다. 정보 은닉의 장점을 구체적으로 한번 알아보자. 시스템 개발 속도를 높인다. 여러 컴포넌트를 병렬로 개발할 수 있기 때문이다. 시스템 관리 비용을 낮춘다. 각 컴포넌트를 더 빨리 파악하여 디버깅할 수 있고, 다른 컴포넌트로 교체하는 부담도 적기 때문이다. 정보 은닉 자체가 성능을 높여주지는 않지만, 성능 최적화에 도움을 준다. 완성된 시스템을 프로파일링해 최적화할 컴포넌트를 정한 다음 다른 컴포넌트에 영향을 주지 않고 해당 컴포넌트만 최적화할 수 있기 때문이다. ..
https://www.acmicpc.net/problem/14501 14501번: 퇴사 첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다. www.acmicpc.net 문제 접근 방법 기간과 비용에 대한 vector를 만들고 그곳에 값을 넣어둔다. 첫날부터 시작하여 일을 하는 경우와 일을 하지 않는 경우로 나뉘어 계산을 진행한다. 계산하여 이전값보다 큰값이면 갱신한다. 아래는 코드입니다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include #include using namespace std;..
아이템 13 : clone 재정의는 주의해서 진행하라 Cloneable은 복제해도 되는 클래스임을 명시하는 용도의 믹스인 인터페이스지만, 아쉽게도 의도한 목적을 제대로 이루지 못했다. 가장 큰 문제는 clone 메서드가 선언된 곳이 Cloneable이 아닌 Object이고, 그마저도 protected라는 데 있다. 그래서 Cloneable을 구현하는 것만으로는 외부 객체에서 clone 메서드를 호출할 수 없다. 실무에서 Cloneable을 구현한 클래스는 clone 메서드를 public으로 제공하며, 사용자는 당연히 복제가 제대로 이루어지리라 기대한다. 이 기대를 만족시키려면 그 클래스와 모든 상위 클래스는 복잡하고, 강제할 수 없고, 허술하게 기술된 프로토콜을 지켜야만 하는데, 그 결과로 깨지기 쉽고,..
아이템 12 : toString을 항상 재정의하라 toString의 규약은 "모든 하위 클래스에서 이 메서드를 재정의하라"이다. toString을 잘 구현한 클래스는 사용하기에 훨씬 즐겁고, 그 클래스를 사용한 시스템은 디버깅하기 쉽다. 실전에서 toString은 그 객체가 가진 주요 정보 모두를 반환하는 게 좋다. toString을 구현할 때면 반환값의 포맷을 문서화할지 정해야 한다. 포맷을 명시하면 그 객체는 표준적이고, 명확하고, 사람이 읽을 수 있게 된다. 따라서 그 값 그대로 입출력에 사용하거나 CSV 파일처럼 사람이 읽을 수 있는 데이터 객체로 저장할 수도 있다. 단점도 있다. 포맷을 한번 명시하면 평생 그 포맷에 얽매이게 된다. 이를 사용하는 프로그래머들이 그 포맷에 맞춰 파싱하고, 새로운 ..
아이템 11 : equals를 재정의하거든 hasCode도 재정의하라 equales를 재정의한 모든 클래스에서 hashCode도 재정의해야 한다. 다음은 Object 명세에서 발췌한 규약이다. equals 비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 실행되는 동안 그 객체의 hashCode 메서드는 몇 번을 호출해도 일관되게 항상 같은 값을 반환해야 한다. 단, 애플리케이션을 다시 실행한다면 이 값이 달라져도 상관없다. equals(Object)가 두 객체를 같다고 판단했다면, 두 객체의 hashCode는 똑같은 값을 반환해야 한다. equals(Object)가 두 객체를 다르다고 판단했더라도, 두 객체의 hashCode가 서로 다른 값을 반환할 필요는 없다, 단, 다른 객체에 대해서는 다른..
https://www.acmicpc.net/problem/1759 1759번: 암호 만들기 첫째 줄에 두 정수 L, C가 주어진다. (3 ≤ L ≤ C ≤ 15) 다음 줄에는 C개의 문자들이 공백으로 구분되어 주어진다. 주어지는 문자들은 알파벳 소문자이며, 중복되는 것은 없다. www.acmicpc.net 문제 접근 방법 입력 받은 문자들을 오름차순으로 정리한다. 원하는 암호의 길이가 될 때까지 공백에서 한문자씩을 더한다. 원하는 길이가 되었을 때 모음과 자음 갯수를 만족하는지 체크한다. 조건이 성립하면 문자를 출력한다. 아래는 코드입니다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34..