본문 바로가기

개발 관련/클린코드13

13. 동시성 동시성이 필요한 이유? 동시성은 커플링(결합)을 없애는 전략이다, 즉 무엇과 언제를 분리하는 전략이다 단일 스레드의 경우 호출 스택을 살펴보면 프로그램 상태가 곧바로 드러난다. 응답 시간과 작업 처리량 혹은 한 번에 한 사람만 처리하는 경우, 정보를 대량으로 분석하는 경우, 이런 경우를 위해 동시성이 필요하다 할 수 있다. 미신과 오해 동시성은 성능을 높여준다 (때때로 높여준다, 각 스레드가 독립적인 행동을 취할 때) 동시성을 구현해도 설계가 바뀌지 않는다 (단일과 다중 스레드 시스템은 설계가 판이하게 다름) 웹 또는 EJB 컨테이너를 사용하면 동시성을 이해할 필요가 없다 (오히려 더 알아야 한다. 동시 수정, 데드락 등을 피하기 위해) 타당한 생각 동시성은 다소 부하를 유발한다 (성능 측면에서 부하가 .. 2022. 7. 13.
12. 창발성 창발적 설계로 깔끔한 코드를 구현하자 켄트 벡이 제시한 단순한 설계 규칙 4가지 모든 테스트를 실행하라 무엇보다도 먼저 설계는 의도한 대로 돌아가는 시스템을 내놓아야 한다. 테스트가 불가능한 시스템은 검증도 불가능하며, 검증이 불가능한 시스템은 출시하면 안된다고 생각한다. 테스트 케이스를 만들고 계속 돌려라 라는 단순한 규칙을 따르면 시스템은 낮은 결함도와 높은 응집력이라는, 객체 지향 방법론이 지향하는 목표를 저절로 달성한다. 중복을 없애라 우수한 설계에서 중복은 커다란 적이다. 똑같은 코드는 당연히 중복이고, 비슷한 코드는 더 비슷하게 고쳐주면 리펙토링이 쉬워진다. 구현 중복도 중복의 한 형태이다. 소규모 재사용은 시스템 복잡도를 극적으로 줄여주고, 추후 대규모 재사용을 가능토록 한다. 프로그래머 의.. 2022. 7. 13.
11. 시스템 시스템 제작과 시스템 사용을 분리하라 제작과 사용은 다르다. 체계적이고 탄탄한 시스템을 만들고 싶다면 흔히 쓰는 손쉬운 기법으로 무듈성을 깨서는 안된다. 설정 논리는 일반 실행 논리와 분리해야 모듈성이 높아진다. Main 분리 시스템 생성과 시스템 사용을 분리하는 한 가지 방법으로, 생성과 관련한 코드는 모두 main 이나 main 이 호출하는 모듈로 옮기고, 나머지 시스템은 모든 객체가 생성되었고 모든 의존성이 연결되었다고 가정한다. 팩토리 때로는 객체가 생성되는 시점을 애플리케이션이 결정할 필요도 생긴다. 이럴 때는 추상 팩토리 패턴을 사용하여 결정은 애플리케이션이 하지만, 생성 코드는 애플리케이션이 모르게 할 수 있다. 의존성 주입 제어의 역전(IoC) 기법을 사용하는데, 한 객체가 맡은 보조 책임.. 2022. 7. 13.
10. 클래스 클래스 체계 공개에서 비공개 형식으로 진행되어 추상화 단계가 순차적으로 내려간다. 캡슐화 변수와 유틸리티 함수는 가능한 공개하지 않는 편이 낫지만 반드시 숨겨야 한다는 법칙도 없다. 테스트에서 사용한다면 protected 도 고려할만하다. 하지만, 그 전에 비공개 상태를 유지할 온갖 방법을 강구한다. 캡슐화를 풀어주는 결정은 언제나 최후의 수단이다. 클래스는 작아야 한다. 클래스는 작아야 한다. 클래스를 설계할 때도 함수와 마찬가지로 '작게' 가 기본 규칙이다. 그렇다면 얼마나 작아야 할까? 함수는 물리적인 행 수로 크기를 측정했다. 클래스에서는 클래스가 맡은 책임을 센다. 클래스 이름은 해당 클래스 책임을 기술해야 한다. 실제로 작명은 클래스 크기를 줄이는 첫 번째 관문이다. 간결한 이름.. 2022. 7. 13.
9. 단위 테스트 TDD 의 법칙 3가지 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다. 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다. 현재 실패하는 테스트를 통화할 정도로만 실제 코드를 작성한다. 깨끗한 코드 유지하기 지저분한 코드를 내놓으나 테스트를 안 하나 오십보 백보이다. 그 이유는 실제 코드가 진화하면 테스트 코드도 변해야 하기 때문이다. 그런데 테스트 코드가 지저분하면 그만큼 수정하기가 어려워진다. 테스트 코드는 실제 코드 못지 않게 중요하다. 테스트 코드는 이류 시민이 아니다. 실제 코드 못지 않게 깨끗하게 짜야 한다. 테스트는 유연성, 유지보수성, 재사용성을 제공한다. 테스트 코드를 깨끗하게 유지하지 않으면 결국은 잃어버린다. 그리고 테스트 케이스가 없으면 .. 2022. 7. 13.
8. 경계 외부 코드 사용하기 인터페이스 제공자와 인터페이스 사용자 사이에는 특유의 경계가 존재한다. 제공자는 사용성을 높이기 위해 많은 영역에서 지원하려고 하고, 사용자는 본인이 사용하는 쪽의 특화된 기능을 원하기 때문이다. 한 가지 예로 Map 을 보면 유용성이 높지만, 그만큼 위험하기도 하다. 여러 유형의 객체를 지원하지만, 오용의 가능성도 높기 때문. 그렇기에 경계 인터페이스를 여기저기 넘기지 않고, Map 과 같은 경계 인터페이스를 이용할 때는 이를 이용하는 클래스나 클래스 계열 밖으로 노출되지 않도록 주의한다. 경계 살피고 익히기 외부 코드를 익히기는 어렵고, 통합하기도 어렵다. 둘을 동시에 하려면 더 어렵다. 그렇기에 우리쪽 코드를 먼저 작성해 외부 코드를 호출하는 대신 먼저 간단한 테스트 케이스를 작.. 2022. 7. 13.