본문 바로가기

전체 글

시스템 소프트웨어 시스템은 제작과 사용을 분리시켜야한다. 제작 : APP 에서 필요한객체를 제작하고 의존성을 서로 연결하는 과정 사용 : 그 이후에 실행하는 런타임 로직 /* Code 1-1 */ public Service getService() { if (service == null) service = new MyServiceImpl(...); // Good enough default for most cases? return service; } Lazy Initialization/Evaluation(게으른 초기화) - 장점 :실제 필요한 객체를 필요할떄까지 생성하지 않아 메모리 부하가 적어지고 앱 실행 속도도 그만큼 빨라진다. - 단점 :MyServiceImpl 객체에 대한 의존성을 가지게 되었고 MyServ.. 더보기
경계(외부 코드를 우리 코드에 깔끔하게 녹여넣기) 외부 코드 사용하기 인터페이스 제공자 와 사용자간의 입장차이 - 인터페이스 제공자 : 최대한 적용성을 넓히려 한다. - 사용자 : 자신의 요구사항에 집중하는 인터페이스 java.util.map clear() void - map containsKey(Object key) boolean - Map containsValue(Object value) boolean - Map entrySet() set - Map equals(Object o) boolean - Map get(Object key)Object - Map getClass() Class 더보기
객체와 자료구조 // 구체적인 Point 클래스 public class Point{ public double x; public double y; } // 추상적인 Point 클래스 public interface Point{ double getX(); double getY(); void setCartesian(double x, double y); double getR(); getter, setter를 추가한다고 해서 구현이 감춰지지 않는다. 구현을 감추려면 추상화가 필요하다. 위는 클래스 구현이 드러나는 자료구조 아래는 사용자가 구현을 모른채 자료를 다루는 함수를 통하는 객체 자료구조는 자료를 그대로 공개하며 별다른 함수를 제공하지 않는다. 객체는 추상화 ㅟ로 자료를 숨긴채 자료를 다루는 함수만을 공개한다. interfa.. 더보기
주석 잘 쓴 주석은 그 어떤 정보보다 유용하나, 경솔하거나 근거 없는 주석은 코드를 오히려 이해하기 어렵게 만든다. 우리가 프로그래밍 언어를 치밀하게 사용해 의도를 표현할 능력이 된다면, 주석은 전혀 필요하지 않다. 우리는 코드로 의도를 표현하지 못해 실패를 만회하기 위해 주석을 사용한다(주석을 달때마다 자신에게 표현력이 없음을 푸념해야 마땅하다.) 코드는 시간이 지날수록 변화하고 여기 저기로 옮겨지기도 한다. 그러나 주석은 코드를 따라기 못한다. 주석은 오래될수록 코드와 멀어지며 그릇될 가능성이 커진다.(주석을 유지보수하기란 현실적으로 불가능) 코드로 의도를 표현하라 // 직원에게 복지 혜택을 받을 자격이 있는지 검사한다. if ((employee.flags & HOURLY_FLAG) && (employee.. 더보기
item 87) 커스텀 직렬화 형태를 고려해보라 기본 직렬화 : Serializable 인터페이스 구현 커스럼 직렬화 : 커스텀 writeObject, readObject 작성 괜찮다고 판단될때만 기본 직렬화 형태를 사용하라. - 객체의 물리적 표현과 논리적 내용이 같다면 사용해도 무방하다. public class Name implements Serializable { /** * 성. null이 아니어야함 * @serial */ private final String lastName; /** * 이름. null이 아니어야 함. * @serial */ private final String firstName; /** * 중간이름. 중간이름이 없다면 null. * @serial */ private final String middleName; } 사람의 이름은.. 더보기
item 88) readObject는 방어적으로 작성하라 - readObject도 바이트 스트림을 인수로 받는 일종의 public 생성자 - 다른 생성자와 똑같은 수준으로 주의를 기울여야한다. - 인수가 유효한지 검사해야하고 필요하다면 매개변수를 방어적으로 복사해야한다.(불변성 유지) public final class Period implements Serializable { //기본 직렬화 사용 private Date start; private Date end; public Period(Date start, Date end) { this.start = new Date(start.getTime()); this.end = new Date(end.getTime()); if (this.start.compareTo(this.end) > 0) { throw new Il.. 더보기
item 82) 스레드 안전성 수준을 문서화하라 멀티스레드 환경에서도 API를 안전하게 사용하게 하려면 클래스가 지원하는 스레드 안전성을 명시해야한다. - 클라이언트의 지나치거나 부족한 동기화를 사용하는 것을 방지한다. 클래스의 스레드 안전성 1) 불변(Immutable) 상수라서 외부 동기화도 필요없다. (Integer, String ....) 2) 무조건적 스레드 안전 : 이 클래스의 인스턴스는 수정될수 있으나 내부에서 충실히 동기화하고 있으므로 별도의 외부 동기화 없이 안전하게 사용할수 있다. (ConcurrentHashMap) 3) 조건부 스레드 안전 : 클래스의 일부 메서드는 동시에 사용하려면 외부 동기화가 필요하다. Collections.synchronized 래퍼 메서드가 반환한 컬렉션들. 4) 스레드 안전하지 않음 : 동시에 사용하려면 .. 더보기
item 81) wait와 notify보다는 동시성 유틸리티를 애용하라 wait와 notify를 꼭 사용해야 할 이유가 줄었다. - 자바 5에서 도입된 고수준의 동시성 유틸리티가 wait, notify를 직접 사용해서 하던 일들을 대신 처리해줌(java.util.concurrent) - 실행자 프레임워크 (Executors) - 동시성 컬렉션(concurent collection) - List, Queue, Map 같은 표준 컬렉션 인터페이스에 동시성을 부여한 것 - 각자 내부에서 동기화를 수행하므로 동시성을 무력화 하는 것이 불가능하고 외부에서 Lock를 사용하면 오히려 속도가 느려진다. - 여러 메서드를 원자적으로 묶어서 호출하는 것 또한 불가능하다. - 여러 기본 동작을 하나의 원자적 동작으로 묶는 상태 의존적 수정 메소드들이 추가되었다. (Java 8 default .. 더보기