# 실전 자바 소프트웨어 개발

# SOLID

# 단일 책임 원칙 single responsibility principle (SRP)

- 한 클래스는 한 기능만 책임진다
- 클래스가 바뀌어야 하는 이유는 오직 하나여야 한다

# 개방/폐쇄 원칙 open/closed principle(OCP)

- 코드베이스에 유연성을 추가하여 유지보수성을 개선(함수형인터페이스)
- 기존의 코드를 변경하지 않으면서, 기능을 추가

# 리스코프 치환 원칙 Liskov substitution principle(LSP)

- 서브 타입은 언제나 기반 타입으로 교체할 수 있어야 한다는 것을 뜻한다.(자식 클래스는 최소한 자신의 부모 클래스에서 가능한 행위는 수행이 보장되어야 한다)
- 하위형식에서 선행조건을 더할 수 없음 (부모가 문서의 크기를 제한하지 않았다면 문서의 크기가 100km 보다 작아야 한다고 요구할 수 없다.)
- 하위형식에서 후행조건을 약화시킬 수 없음 (부모가 부작용을 포함하거나 어떤 값을 반환한다면 자식도 그래야 한다)
- 슈퍼형식의 불변자는 하위형식에서 보존됨 (부모 클래스에서 유지되는 모든 불변자는 자식 클래스 에서도 유지되어야 한다)
- 히스토리 규칙 (자식 클래스는 부모가 허용하지 않은 상태변화를 허용하지 않아야 한다)

# 인터페이스 분리 원칙 interface segregation principle(ISP)

# 의존관계 역전 원칙 dependency inversion principle(DIP)

# 클래스 수준 응집도

실무에서는 일반적으로 다음과 같은 여섯가지 방법으로 그룹화 한다

# 기능

- parseFrom() 과 parseLinesFrom() 은 csv 형식의 행을 파싱한다.
- 내부적으로 parseLinesFrom() 메서드는 parseFrom() 메서드를 사용한다.
- 따라서 이 둘을 그룹화

# 정보

- 같은 데이터나 도메인 객체를 처리하는 메서드를 그룹화 하는 방법
- bankTransaction 객체에서 CRUD 기능 만을 제공하는 메서드를 만든다.
- 이와같은 유형은 테이블이나 특정 도메인 객체를 저장하는 데이터베이스와 상호작용할 때 흔히 볼 수 있다. 이 패턴을 보통 `데이터 접근 객체 data access object(DAO)`라 부르며 객체를 식별하는 일종의 ID가 필요함.
- DAO는 영구저장 데이터베이스나 인메모리 데이터베이스 같은 데이터 소스로의 접근을 추상화 하고 캡슐화 한다
- 정보 응집은 여러 기능을 그룹화 하면서, 필요한 일부 기능을 포함하는 클래스 전체를 디펜던시로 추가한다는 약점이 있다.

# 유틸리티

- 관련 없는 메서드를 한 클래스로 포함시켜야 할 때
- 낮은 응집도로 이어지므로 자제해야한다.

# 논리

- CSV, JSON, XML 자료를 파싱하는 코드를 한 클래스로 그룹화.
- 하지만 이들은 본질적으로 다름
- 또한 이렇게 그룹화 하면 한 클래스는 네가지 책임을 갖게 되므로 SRP를 위배한다. 따라서 권장하지 않음

# 순차

- 파일을 읽고, 파싱하고, 처리하고 정보를 저장하는 메서드를 한 클래스로 그룹화.
- 입출력이 순차적으로 흐르는 것을 순차응집이라고 한다.
- 한 클래스를 바꿔야 할 여러 이유가 존재하므로 SRP 위배

# 시간

- 어떤 작업을 처리하기 전과 뒤 를 담당하는 메서드를 포함하는 클래스.
- 각 동작을 이해하고 사용하기 어려움

# 결합도

  • 한 기능이 다른 클래스에 얼마나 의존하고 있는지, 어떤 클래스를 구현하는데 얼마나 다른 클래스를 참조했는가
  • 인터페이스를 활용하여 결합도를 제거할 수 있다.

# 함수형 인터페이스

한개의 추상 메서드를 포함하는 인터페이스. @FunctionalInterface 애너테이션 이용 하여 인터페이스의 의도를 더 명확하게 표현할 수 있다.

# java에서 예외

  • 문서화 : 메서드 시그니처 자체에 예외를 지원한다
  • 형식 안정성 : 개발자가 예외 흐름을 처리하고 있는지를 형식 시스템이 파악한다
  • 관심사 분리 : 비즈니스 로직과 예외 회복이 각각 try/catch 블록으로 구분된다.

# 예외 종류

  • 확인된 예외 : 회복해야 되는 대상의 예외다. 자바에서는 메서드가 던질 수 있는 확인된 예외 목록을 선언해야 한다. 아니면 해당 예외를 try/catch로 처리. Exception
  • 미확인 예외 : 프로그램을 실행하면서 언제든 발생할 수 있는 예외. 확인된 예외와 달리 메서드 시그니처에 명시적으로 오류를 선언하지 않으면 호출자도 이를 꼭 처리할 필요가 없다. Error RuntimeException

# 노티피케이션 패턴

  • 도메인클래스로 오류를 수집.

# 예외 사용 가이드라인

  • 예외를 무시하지 않음 : 명확하지 않을땐 미확인 예외를 대신 던진다.
  • 일반적인 예외는 잡지 않음 : 일반적인 Exception은 RuntimeException도 포함한다.
  • 예외 문서화 : javadoc
  • 특정 구현에 종속된 예외를 주의할것 : 캡슐화가 깨지므로 주의하자.
  • 예외 vs 제어흐름 : 예외로 흐름을 제어하지 않는다
  • 예외 대신 null 반환, null 객체 패턴: 하지 말것
  • Optional
  • Try

# 유비쿼터스 언어

도메인 주도 설계에서 처음 등장. 개발자와 사용자 모두가 사용할 수 있도록 설계, 공유된 공통 언어를 말한다.

# 발견성

동료나 고객과 대화할때 사용하는 용어를 응용프로그램의 코드와 같은 의미로 사용하면 유지보수가 쉬워진다. 소프트 웨어의 기능을 공통 언어로 약속한다. 이때 사용한 어휘를 코드오 매핑하면 코드의 어떤 부분을 바꿔야 하는지 쉽게 알 수 있다.

# 도메인 클래스

도메인 클래스를 이용하면 개념에 이름을 붙이고 수행할 수 있는 동작과 값을 제한하므로 발견성을 개선하고 버그 발생 범위를 줄일 수 있다.

# TDD

테스트 주도 개발 Test-driven development. 테스트 코드를 먼저 만든 후 이에 맞춰 코드를 구현하는것.

# TDD 주기

  1. 실패하는 테스트 구현
  2. 모든 테스트 시행
  3. 기능이 동작하도록 코드 구현
  4. 모든 테스트 실행