본문 바로가기

독후감

(15)
1. 도메인 모델 시작하기 도메인 모델 패턴 애플리케이션 아키텍처는 아래와 같이 4개의 영역으로 구성된다. 도메인 모델은 아키텍처 상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴을 말한다. 영역 설명 Presentation 사용자의 요청을 처리하고 사용자에게 정보를 보여준다. Application 사용자가 요청한 기능 실행(업무 로직을 직접 구현하지 않으며 도메인 계층을 조합해서 기능을 구성) Domain 시스템이 제공할 도메인 규칙 구현 Infrastructure DB나 메시징 시스템과 같은 외부 시스템과의 연동 처리 도메인 계층에만 핵심 규칙을 구현한 코드가 위치하기에 규칙이 바뀌거나 규칙을 확장할 때 다른 코드에 영향을 덜 주고 변경 내역을 모델에 반영할 수 있다. Entity 와 Value Entity 엔티티의 가장 ..
[독후감] 자바 성능 튜닝 이야기 '자바 성능 튜닝 이야기' - 이상민님 실제 웹 서비스에서 사용될만한 자바 성능과 관련된 이야기를 담은 책이다. 책의 도입부만 읽었을 때 아래와 같은 내용들이 나와 초급자용 코딩 관련 튜닝 책이라고 생각했다. - String / StringBuilder / StringBuffer의 차이 - List, Set, Map 등의 자료구조 - for, forEach 등의 차이 물론 심오하게 파면 어려울 수 있겠으나, 업무를 진행하며 인터넷이나 자바 기초 서적과 같은 곳에서 볼법한 이야기를 담았기 때문이다. 그러나 기존에 단순하게 Java로 개발하여 웹서버에 올리기만 한 나에게 있어 책의 중반부를 넘어서며, 웹서버 관련 이야기가 나오면서부터 튜닝 관련 난이도가 높아지기 시작했다. 웹서버에서 성능을 높이기 위해 필요..
10. equals는 규칙에 맞게 재정의하라 equals 메서드는 재정의하기 쉬워 보이지만 사실 문제가 많다. 문제를 회피하는 가장 쉬운 길은 아예 재정의하지 않는 것이다. 클래스에 equals를 정의하지 않는다면 그 클래스의 인스턴스는 오직 자기 자신과만 같게된다. 그러니 다음에서 열거한 상황 중 하나에 해당한다면 재정의하지 않는 것이 최선이다. 각 인스턴스가 본질적으로 고유해야 한다. 인스턴스의 동등성을 검사할 필요가 없다. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다. 클래스가 private이거나 package-private이고, equals를 호출할 일이 없다. 만약 equals메서드에 대한 실수를 좀 더 철저히 막고 싶다면 @Override public boolean equals(Object o) { throw n..
9. try-finally 보다는 try-with-resources를 사용하라 자바 라이브러리에는 close메서드를 활용해 직접 닫아줘야 하는 자원이 많다. 이런 경우 자바에서는 전통적으로 try-finally가 사용되었다. 하지만 try-finally는 닫아줘야하는 자원이 2개만 되어도 굉장히 난잡해진다. static void copy(String src, String dst) throws IOException { InputStream in = new FileInputStream(src); try { OutputStream out = new FileOutputStream(dst); try { byte[] buf = new byte[BUFFER_SIZE]; int n; while((n = in.read(buf)) >= 0) out.write(buf, 0, n); } finally ..
8. finalizer와 cleaner 사용을 피하라
7. 다 쓴 객체 참조를 해제하라 자바같은 가비지 컬렉션을 가진 언어에서는 메모리 누수를 찾기가 매우 어렵다.객체 참조를 하나라도 살려두면 가비지 컬렉터는 그 객체뿐 아니라 그 객체가 참조하는 모든 객체를 회수하지 못 한다. 이를 해결하는 방법은 간단하다. 해당 참조를 다 썻을 때 null 처리 해주면 된다. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { this.elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { this.ensureCapa..
6. 불필요한 객체 생성을 피하라 다음은 정규표현식을 활용한 예제이다. static boolean isRomanNumera(String s) { return s.matches("^(?-.)M* ....; } 성능을 개선하려면 필요한 인스턴스를 클래스 초기화과정에서 생성해 캐싱하여, 나중에 해당 인스턴스를 재사용한다.이 방식은 쉬운 방식이지만 성능이 중요한 곳에서는 반복적으로 사용하기 적합치 않다. 이 메서드가 내부에서 만드는 인스턴스는 한 번 쓰이고 버려져 곧바로 가비지 컬렉션 대상이 된다. public class RomanNumerals { private static final Pattern ROMAN = Patterm.compile( "^(?-.)M* .... ); static boolean isRomanNumeral(String s..
5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다. public class SpellChecker { // 유연하지 않고 테스트하기 어렵다. private final Lexicon dictionary = ...; public SpellChecker(Lexicon dictionary) { this.dictionary = Objects.requireNonNull(dictionary); } }​ 클래스가 여러 자원 인스턴스를 지원해야 하며, 클라이언트가 원하는 자원을 사용해야 한다. 이 조건을 만족하는 패턴이 있으니, 바로 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식이다. public class SpellChecker { // 유연하지 않고 테스..