참고
1. 목차
NOTE
•
•
목차
NOTE
•
•
목차
NOTE
•
•
목차
NOTE
•
개념은 빈행으로 분리하자 (엔터키좀 눌려라)
•
관련된건 가까이두자 (엔터키 남발하지마라)
•
변수는 최대한 사용하는 곳과 가까이둬라
•
인스턴스 변수는 무조건 클래스 처음에 선언해라
◦
C++은 마지막에 선언한다는 가위 규칙이 있다고함
◦
Java는 그런거 없다
•
하나의 함수가 다른 함수를 호출한다면 최대한 가까이 둬라
•
함수를 호출하는 함수는 먼저 배치하고, 호출되는건 나중에 배치해라 종속성은 아래 방향으로 유지한다.
•
가로형식 ⇒ 대충 20~60자 정도로 유지해라
•
가로정렬은 생각보다 별 쓸모없다. 선언부가 길면 클래스를 쪼개라
•
들여쓰기는 겁나 중요하다
•
코드는 언제나 읽기 좋아야 한다. 스타일은 일관적이고 매끄러워야 한다.
객체와 자료구조
NOTE
•
자료 추상화
◦
자료를 세세하게 공개하기보다 추상적인 개념으로 표현하는것이 좋다.
◦
절차적인 코드
▪
기존 자료 구조를 변경하지 않으면서 새 함수 추가하기가 쉽다.
▪
새로운 자료구조를 추가하기 어렵다. 그러려면 모든 함수를 고쳐야한다.
◦
객체지향 코드
▪
기존 함수를 변경하지 않으면서 새 클래스를 추가하기 쉽다.
▪
새로운 함수를 추가하기 어렵다. 그러려면 모든 클래스를 고쳐야 한다.
•
객체 지향 코드에서 어려운 변경은 절차적인 코드에서 쉽다. (반대도 마찬가지)
•
무조건 객체지향이 절차지향보다 나은건 아니다. 때로는 단순한 자료구조와 절차코드가 더 적합할때가 있다.
•
디미터 법칙
◦
모듈은 자신이 객체의 속사정을 몰라야 한다는 법칙
◦
객체는 조회 함수로 내부 구조를 공개하면 안된다.
◦
클래스 C의 메서드 f는 다음과 같은 객체의 메서드만 호출한다
◦
위 객체에서 허용된 메서드가 반환하는 객체의 메서드는 호출하면 안된다.
•
기차 충돌
여러 객차가 한줄로 이루어진 기차처럼 보인다.
이렇게 나누는게 좋음
•
잡종 구조
◦
중요한 기능을 수행하는 함수도 있고, 공개 변수나 공개 조회/설정 함수도 있다.
◦
공개 조회/설정 함수는 비공개 변수를 그대로 노출한다.
◦
절대 하면안되는 구조임
•
자료 전달 객체
◦
자료 구조체의 전형적인 형태는 공개 변수만 있고 함수가 없는 클래스다.
◦
자료 구조체 ⇒ Data Transfer Object, DTO
◦
좀 더 일반적인 형태는 Bean 구조
•
활성 레코드
◦
DTO의 특수 형태
◦
비공개 변수에 조회/설정 함수가 있는 자료구조
◦
save나 find같은 탐색함수도 제공한다.
•
결론
◦
객체는 동작을 공개하고 자료를 숨긴다.
▪
기존 동작을 변경하지 않으면 새 객체 타입을 추가하기는 쉬운 반면, 기존 객체에 새 동작을 추가하기는 어렵다.
◦
자료 구조는 별다른 동작 없이 자료를 노출한다.
▪
새 동작을 추가하기는 쉬우나, 기존 함수에 새 자료구조를 추가하기 어렵다.
◦
새로운 자료 타입 추가하는 유연성이 필요 ⇒ 객체
◦
새로운 동작 추가하는 유연성이 필요 ⇒ 자료구조
오류처리
NOTE
•
오류보다 예외써라
◦
예외 try-catch-finally 문부터 작성하는게 좋다.
•
미확인 예외를 사용하라
◦
unchecked 예외가 더 좋음 checked는 상위 메소드에 모두 throws를 달아줘야함
•
예외에 의미를 제공하라
◦
전후 상황을 충분히 줘야한다. 그래야 오류가 발생한 원인과 위치를 찾기 쉬워진다.
◦
자바는 모든 예외에 호출 스택을 제공하지만 그걸론 부족하다.
•
호출자를 고려해 예외클래스 정의
하나의 유형으로 좁힘
•
null을 반환하지마라
위의 코드는 null이 아니라 빈객체 반환시키는게 더 좋음
◦
null 체크로 한세월이니깐 하지마라
•
null을 전달하지 마라
◦
assert 문 사용해서 이상한 인자값 확인하
경계
NOTE
•
외부 코드 사용하기
자바의 map은 엄청많은 메서드를 제공한다.
◦
Map이 경계 인터페이스라는데 무슨말인지 잘모르겠음
◦
Map과 같은 경계 인터페이스를 사용할 때, 클래스나 클래스 계열 밖으로 노출되지 않도록 주의해야 한다.
•
log4j
◦
로깅을 잘하자
•
아직 존재하지 않는 코드를 사용하기
◦
인터페이스를 잘 설계하면 통제면에서 좋다?
테스트 코드
NOTE
•
TDD 법칙 3가지
◦
실패하는 단위 테스트를 작성할 떄 까지 실제 코드 작성하지 않음
◦
컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트 작성
◦
현재 실패하는 테스트를 통과할 정도로만 실제 코드 작성
•
테스트 코드가 너무 많아져도 유지보수하기 힘들다
•
꺠끗한 테스트 코드
◦
무조건 가독성이 좋아야 함 ㅇㅇ
◦
BUILD - OPERATE - CHECK 패턴이 좋음
◦
given when then 인가?
•
도메인에 특화된 테스트언어
•
테스트당 assert 하나
•
FIRST 기법
•
애초에 실제 클린 테스트 코드를 배울려면 책1권이 필요하다.
◦
이건 수박 겉햟기
클래스
NOTE
•
클래스 체계
◦
변수 목록이 먼저 나와야함
1.
정적 공개
2.
정적 비공개
3.
비공개 인스턴스 변수
4.
공개 변수는 거의 필요한일이 없음
•
클래스는 작아야 한다.
◦
단순 코드길이가 아니라, 책임이 1개만 있어야 한다는 것
◦
클래스 설명을 만일(if), 그리고, 또는, 하지만을 사용하지 않고 25단어로 설명이 되야함
•
단일 책임 원칙
◦
클래스나 모듈을 변경할 이유가 하나 뿐이어야 한다. (SOLID의 SRP 법칙)
•
응집도
◦
인스턴스 변수가 적어야 한다.
◦
변수가 많다 ⇒ 응집도가 높다는 의미
◦
응집도를 유지하면 작은 클래스가 여럿이 나온다.
•
변경하기 쉬운 클래스
◦
클래스 일부에서만 사용되는 비공개 메서드는 코드를 개선할 잠재적인 여지를 서사한다.
◦
클래스를 분리해서 단순하게 만듬
•
변경으로부터 격리
시스템
NOTE
•
도시를 세운다면?
◦
도시를 세우고 혼자 관리하는건 절대 불가능하다.
◦
적절한 추상화 모듈이 중요하다 ⇒ 큰 그림을 몰라도 개인이 관리하는 구성요소는 효율적으로 돌아간다.
•
시스템 제작과 사용을 분리
◦
관심사 분리 기법
◦
초기화 지연, 계산 지연 기법
▪
이게 항상 옳은지 고민해봐라
•
Main 분리
모든 화살표는 main → 애플리케이션
객체 생성시점을 애플리케이션이 결정하는 경우
•
의존성 분리
◦
사용과 제작을 분리하는 강력한 매커니즘
◦
제어역전 (IOC)기법을 적용한 매커니즘
◦
한 객체가 맡은 보조 책임을 새로운 객체에게 전적으로 넘긴다.
▪
스프링 DI 컨테이너
•
확장
◦
처음부터 올바른 시스템을 만드는건 어렵다
◦
오늘 주어진 요구에 맞춰 구현하고, 내일은 새로운 요구에 맞춰 구현해야한다
▪
에자일 방식의 핵심
•
횡단관심사, 자바 프록시, AOP
•
AspectJ 관점
◦
AOP 구현하는데 사용함
•
빅 디자인 업 프론트(모든 요구사항을 설계) 하는건 추구하지 ㅇ낳아도된다.
◦
간단한거 만들며 분리된 아키텍쳐로 진행해 결과물을 빨리 만들어라
•
시스템은 도메인 특화 언어가 필요하다.
◦
좋은 DSL은 코드 사이에 존재하는 의사소통 간극을 줄여준다.
◦
추상화 수준을 디자인 패턴 이상으로 끌어올려
창발성
NOTE
•
무조건 따르기만하면 우수한 설계가 나오는 4가지
◦
모든 테스트를 실행한다
▪
테스트를 다 작성하면 리팩토링으로 코드 수정
◦
중복을 없앤다
▪
이것도 리팩토링 개념
▪
디자인패턴을 잘 배우자(책에서는 템플릿 메소드로 설명)
◦
프로그래머 의도를 표현한다
▪
좋은 이름
▪
함수 클래스 크기 줄이기
▪
표준명칭 사용
▪
단위 테스트 잘 작성
▪
표현력 높이기 위해선 노오력이 중요
◦
클래스와 메서드의 수를 최소로 줄인다.
▪
극단적인 SRP를 추구하면 오히려 실이 많아진다.
▪
이 규칙은 4개의 규칙중 가장 우선순위가 낮다.
동시성
NOTE
•
동시성과 깔끔한 코드는 양립하기 어렵다
◦
동시성은 결합을 없애는 전략이다.
◦
무엇, 언제를 분리하는 전략
◦
서블릿 모델을 잘 보자
▪
동시성을 부분적으로 관리한다.
▪
요청 들어옴 → 웹 서버가 비동기적으로 서블릿 실행
▪
서블릿 프로그래머는 모든 요청에 대해 관리할 필요가 없다.
▪
각 서블릿 스레드는 다른 서블릿 스레드와 무관하게 돌아감
◦
정보 수집기
▪
단일 스레드 ⇒ 하나의 사이트, 하나의 정보 추출, 한번에 하나의 사용자
▪
이런걸 병렬로 처리해야함
•
동시성은 어렵지만 관련된 오해가 많다. (아래는 미신과 오해)
◦
동시성은 항상 성능을 높인다
▪
동시성은 떄로 성능을 높여준다.
▪
대기시간이 아주 길어 프로세서를 공유하거나, 독립적인 계산이 충분히 많은 경우에 유용하다.
◦
동시성을 구현해도 설계는 변하지 않는다.
▪
단일, 다중 스레드 시스템은 다르다
◦
웹 또는 EJB 컨테이너를 사용하면 동시성을 이해할 필요 없다.
▪
어떻게 컨테이너가 동작하는가, 동시 수정, 데드락등 어떻게 피하는지 알아야함
•
동시성에 대한 타당한 생각
◦
동시성은 다소 부하를 유발한다. (성능 측면에서 부하가 걸림)
◦
동시성은 복잡하다.
◦
동시성을 구현하려면 근본적인 설계 전략을 재고해야한다.
•
동시성 방어 원칙
◦
단일 책임 원칙
▪
동시성 코드는 다른 코드와 분리하라
▪
동시성 코드는 독자적인 개발, 변경, 조율 주기가 있다.
▪
동시성 코드에는 독자적인 난관이 있다.
◦
따름 정리 (자료범위 제한)
▪
임계영역을 synchronized 키워드로 보호하라고 권장한다.
▪
자료를 캡슐화하고, 공유 자료를 최대한 줄여라
▪
자료 사본을 사용해라
▪
스레드는 가능한 독립적으로 구현해라
◦
실행 모델을 이해하라
실행 모델 개념
▪
생산자 소비자
•
하나 이상의 생산자 스레드가 정보를 생성해 버퍼나 대기열에 넣는다.
•
하나 이상의 소비자 스레드가 대기열에서 정보를 가져와 사용한다.
•
대기열은 한정된 자원이다.
•
생산자 → 정보를 채웠다고 소비자에게 알림
•
소비자 → 정보를 읽어들인 후 빈공간이 있다고 알려준다.
▪
읽기-쓰기
•
읽기 쓰레드의 경우 공유자원을 주로 쓰지만, 쓰기 쓰레드가 공유 자원을 갱신한다 생각하자
•
이 경우 처리율이 핵심이다. ⇒ 처리율을 강조하면 기아 현상이 생기거나 오래된 정보가 쌓인다.
•
읽기 쓰레드가 없을 때 까지 갱신을 원하는 쓰기 쓰레드가 버퍼를 기다린다.
•
읽기 쓰레드가 계속 생기면 쓰기 쓰레드는 기아 현상에 빠짐
•
쓰기 쓰레드에 우선권을 주면 처리율이 떨어진다.
◦
동기화 부분을 작게 만들어라
◦
올바른 종료코드는 구현하기 어렵다.
◦
말이 안되는 일단 스레드 문제로 취급해라
◦
다중 스레드 이전에 순차 코드부터 제대로 만들자
◦
프로세서 수 보다 많은 스레드를 돌려보자
◦
자동화
▪
보조 코드를 자동으로 추가할때 AOP를 사용할 수 있다.
▪
점진적인 개선
NOTE
•
•
JUnit 프레임워
NOTE
•
•
점진적인 개선
NOTE
•
•
1. 목차
NOTE
•
•
목차
NOTE
•
•