책읽기/클린코드 (21) 썸네일형 리스트형 동시성 객체는 처리의 추상화다. 스레드는 일정의 추상화다. 동시성이 필요한 이유 ? 동시성은 무엇과 언제를 분리하여 결합을 없앤다. 응답 시간, 작업 처리량 개선을 위한 동시성이 필요할 수 있다. 동시성의 미신, 오해 동시성은 항상 성능르 높여준다. -> 대기 시간이 아주 길어 여러 스레드가 프로세서를 공유하거나, 여러 스레드가 동시에 처리할 독립적 계산이 충분히 많은 상황에만 높아진다. 동시성을 구현해도 설계는 바뀌지 않는다. -> 무엇과 언제를 분리하므로 판이하게 다르다. 웹, EJB 컨테이너를 사용하면 동시성을 이해하지 않아도 된다. -> 컨테이너가 어떻게 동작하는지 알아야 문제에 대처가 가능하다. 동시성에 대한 타당한 생각 동시성은 다소 부하를 유발한다. 동시성은 복잡하다. 일반적으로 동시성 버그는 재현.. 창발성 창발(創發)또는 떠오름 현상은 하위 계층(구성 요소)에는 없는 특성이나 행동이 상위 계층(전체 구조)에서 자발적으로 돌연히 출현하는 현상이다. 또한 불시에 솟아나는 특성을 창발성 또는 이머전스라 한다. - wikipedia 설계규칙 (중요도순) 1. 모든 테스트를 실행한다. 2. 중복을 없앤다. 3. 프로그래머 의도를 표현한다. 4. 클래스와 메서드 수를 최소로 줄인다. 1. 모든 테스트를 실행한다. 모든 테스트를 작성한다. 결합도가 높으면 테스트 케이스를 작성하기 어렵다. 모든 테스트를 작성하다 보면 테스트가 어려운 모듈이 존재할 것이고, 고칠 부분을 찾을 수 있다. 고칠 부분을 찾아서, 의존성 주입, 인터페이스, 추상화등을 이용하여 결합도를 낮추면 좋은 코드를 얻는다. 2. 리펙토링 나머지 2, 3,.. 시스템 복잡성은 죽음이다. 개발자에게서 생기를 앗아가며, 제품을 계획하고 제작하고 테스트하기 어렵게 만든다. - Ray Ozzie. 마이크로소프트 최구 기술 책임자 시스템 제작과 시스템 사용을 분리하라 소프트웨어 시스템은 에플리케이션 객체를 제작하고 의존성을 서로 연결하는 준비 과정과 런타임 로직을 분리해야 한다. 아래는 Lazy Initialization, 초기화 지현 이라는 기법이다. 아래에서 getService() 는 애플리케이션이 실행되며 기능에 필요한 런타임 로직이다. 하지만 이 런타임 로직 안에서 new MyServiceImpl() 이라는 객체생성, 즉 준비 과정(시작 단계) 를 섞어 쓰고 있다. 준비 과정은 모든 애플리케이션이 풀어야할 관심사 이며, 관심사는 분리 해야 한다. private Serv.. 클래스 클래스 체계 클래스 내부에서는 다음과 같은 순서가 보통의 컨벤션이다. class A { public static 상수 private static 변수 private 인스턴스 변수 public 메서드 public 메서드에 딸린 priavet 메서드 } 변수나 메서드는 보통 캡슐화를 하여 구현을 뒤로 숨기는 것이 좋다. 우리는 항상 캡슐화를 푸는 것을 신경써야 한다. 하지만 때로는 테스트 코드에서 접근하기 위해 protected 로 선언하기도 한다. 테스트는 매우 중요하기 때문이다. 클래스는 작아야 한다 클래스의 이름은 해당 클래스의 책임을 기술한다. 좋은 클래스 이름을 짓게 되면, 해당 클래스가 맡은 책임이 분명해진다. Processor, Manager, Super 과 같이 모호한 단어가 이름에 있다면 여.. 단위 테스트 TDD 의 세가지 법칙 1. 실패하는 단위 테스트를 작성한다. 2. 실패하는 테스트를 통과할 정도로만 코드를 작성한다. 3. 리펙토링. 깨끗한 테스트 코드 유지하기 테스트는 유연성, 유지보수성, 재사용성을 제공한다. 단위테스트는 테스트의 유연성, 유지보수성, 재사용성을 제공한다. 테스트 케이스가 있다면 코드가 변경되었을때, 재대로 변경되었는지의 여부를 알기 쉽다. 따라서 잘 짜여진 자동화된 테스트 케이스는 변경을 쉽게 만든다. (테스트 케이스가 지저분하다면 코드를 변경하기 힘들 것이고, 결국 지저분한 코드가 될 것이다.) 깨끗한 테스트 코드 깨끗한 테스트 코드는 역시 가독성 이 제일 중요하다. BUILD-OPERATE-CHECK 패턴은 가독성을 늘리기에 좋다. BUILD : 테스트 자료를 만든다. OPE.. 경계 프로그램을 개발하다 보면 우리는 외부의 코드를 우리의 코드에 통합해야 할 일이 많이 생긴다. 이번 장은 이 소프트웨어의 경계를 깔끔하게 처리하는 방법에 대해 다룬다. 외부 코드 사용하기 예를 들어 Map 을 만들어 여기저기 뿌린다고 생각해보자. java.util.Map 이 제공하는 메서드 중에는 clear() 이 있다. Map 을 받아 이용하는 클라이언트 중 누군가 clear() 를 실행해버리면 큰일이 날 것이다. 또는 Map에 특정 자료형만 저장하기로 약속했다고 하자. 하지만 누군가가 add() 를 통해 다른 객체 유형을 넣지 않을 것이란 보장이 있는가? 두번쨰 문제점은 제네릭스를 이용하면 해결되지만 첫번째 문제점을 해결해 주지는 않는다. 이 문제에 대하여 해결책은, 다른 사람들이 쓸 이 경계 Map .. 오류 처리 1. 오류 코드보다 예외를 사용하라. 지금은 try / catch 구문을 이용하여 예외를 처리하는 방법을 많이 사용하지만 이전에는 그냥 if 문을 통해 오류코드를 반환하고 처리를 했나보다. try / catch를 이용하면 try에서 호출자 코드를 작성하고 catch에서 오류 코드가 분리되기 때문에 깔끔하다. 2. try / catch 구문을 먼저 작성하라. try 안에 있는 구문은 어느 시점에서든 실행이 중단 된 후 catch 로 넘어갈 수 있다. catch 블록은 try 블록에서 어떤일이 생기든 프로그램의 일관성을 유지해야한다. 따라서 예외가 발생할만한 코드는 try / catch 구문을 써놓고 안을 작성하는 것이 좋다. 자연스럽게 try / catch 문 부터 작성하는 방법은 먼저 강제로 예외가 발생.. 객체와 자료 구조 변수는 보통 private 형으로 정의한다. 캡슐화를 통해 외부에서 접근하지 못하게 한다. 의존성을 없애서 구현을 맘대로 변경하기 위해서다. 1. 자료 추상화 포인트 라는 자료구조를 나타내는 클래스가 있다. public class Point { public double x; public double y; } 이 클래스의 인스턴스 변수는 public 으로 선언되어 값에 직접 접근이 가능하다. 이는 클래스간의 의존성을 높이고 결합도를 높인다. 그래서 인스턴스 변수를 priavte으로 바꾸고 추상 인터페이스를 만들었다. public interface Point { double getX(); double getY(); void setCartesian(double x, double y); double getR().. 이전 1 2 3 다음