- 함수와 클래스 등의 추상화로 실질적 인 코드를 숨기면, 사용자가 세부 사항을 알지 못해도 괜찮다는 장점이 있음
- 가장 간단한 추상화는 상수(constantvalue)
- 리터럴은 아무것도 설명하지 않음. 따라서 코드에서 반복적으로 등장할 때 문제가 됨.
- 리터럴울상수프로퍼티로 변경하면 해당값에 의미 있는 이름을 붙일 수 있으며, 상수의 값을 변경해야 할 때 훨씬 쉽게 변경할 수 있음
- 상수로 빼낸다면 훨씬 쉽게 이해할 수 있을 것
const val MIN_pASSWORD_LENGTH = 7
- 상수로 추출하면 이름을 붙일 수 있고, 나중에 해당 값을 쉽게 변경할 수 있음
- 메시지의 출력 방법이 바뀔 수 있다는 것을 알고 있다면, 이때부터 중요한 것 은 메시지의 출력 방법이 아니라, 사용자에게 메시지를 출력하고 싶다는 의도 자체
- 그냥 이름 변경은 별 큰 차이가 없다고 생각하지만 컴파일러의 관점에서만 유효함. 사람의 관점에서는 이름이 바뀌 면 큰 변화가 일어난 것. 함수는 추상화를 표현하는 수단이며, 함수 시 그니처는 이 함수가 어떤 추상화를 표현하고 있는지 알려주므로 의미 있는 이름은 굉장히 중요함
- 함수는 매우 단순한 추상화지만 제한이 많음.
- 함수는 상태를 유지하지 않으며 함수 시그니처를 변경하면 프로그램 전체에 큰 영향 울 줄 수 있음
- 구현을 추상화할 수 있는 더 강력한 방법으로는 클래스가 있음
- 클래스가 함수보다 더 강력한 이유는 상태를 가질 수 있으며, 많은 함수를 가 질 수 있다는 점 때문
- 클래스는 훨씬 더 많은 지유를 보장
- 한계: 클래스가 final이라면, 해당 클래스 타입 아래에 어떤구현 이 있는지 알 수 있음
- open 클래스는 서브클래스를 대신 제공할 수 있기 때문에 open ****클래스를 활용하면 조금은 더 자유를 얻을 수 있음
- 더 많은 자유를 얻으려면, 인터페이스 뒤에 클래스를 숨겨 더 추상적이게 만들면 됨.
- 코틀린 표준 라이브러리를 읽어보면, 거의 모든 것이 인터페이스로 표현됨
- 실질적인 클래스는 일반적으로 private
- 함수 lazy는 Lazy 인터페이스를 리턴함
- 라이브러리를 만드는 사람은 내부 클래스의 가시성을 제한하고, 인터페이스를 통해 이를 노출하는 코드를 많이 사용함
- 이렇게 하면 사용자가 클래스를 직접 사용하지 못하므로, 라이브러리를 만드는 사람은 인터페이스만 유지한다 면, 별도의 걱정 없이 자신이 원하는 형태로 그 구현을 변경할 수 있음
- 인터페이스 뒤에 객체를 숨김으로써 실질적인 구현을 추상화하고, 사용자가 추상화된 것에만 의존하게 만들 수 있어 결합(c)oupling을 줄일 수 있음
- 코틀린은 멀티 플랫폼 언어이기 때문에 listOf가 코틀린/JVM, 코틀란JS, 코틀린네이티브에 따라서 구현이 다른 리스트를 리턴함
- 다른 리스트를 사용하는 이유는 최적화 때문. (각 플랫폼의 네이티브 리스트를 사용해서 속도를 높이는 것)
- 어떤 플랫폼을 사용해도 List 인터페이스에 맞춰져 있으므로, 차이 없이 사용할수 있음
- 또 다른 장점은 테스트할 때 인터페이스 페이킹(faking)이 클래스 모킹(mocking)보다 간단하므로, 별도의 모킹 라이브러리 (mocking libra자)를 사용하지 않아도 됨
- 실제 클래 스를 자유롭게 변경할 수 있음
- 사용 방법을 변경하려면, Message Display 인터페이스를 변경하고, 이를 구현하는 모든 클래스를 변경해야 함.
- 더 많은 추상화는 더 많은 자유를 주지만, 이를 정의하고, 사용하고, 이해하는 것이 조금 어려워짐
- 상수로추출한다.
- 동작을 함수로 래핑한다.
- 함수를 클래스로 래핑한다.
- 인터페이스뒤에클래스를숨긴다.
- 보편적인 객체 (universal object)를 특수한 객체 (specialistic object)로 래핑한다.
- 추상화를 구현할 떄의 도구
- 제네릭 타입 파라미터를사용한다.
- 내부 클래스를 추출한다.
- 생성을 제한한다(예를 들어 팩토리 함수로만 객체를 생성할 수 있게 만드는 등)
- 추상화는 자유를 주지만 코드를 이해하고 수정하기 어렵게 만듦
- 큰 프로젝트에서는 잘 모듈화해야 함
- 추상화도 비용이 발생하기 때문에 극단적으로 모든 것을 추상화해서는 안됨
- FizzBuzz는 10줄도 필요하지 않은 간단한 예
- FizzBuzz Enterprise Edition에는 61개의 클래스와 26개의 인터페이스가 있음
- https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
- 추상화가 너무 많으면 코드를 이해하기 어려움
- 추상화가 많온 코드를 보면, 이해하기 어렵다는 생각 때문에 코드를 제 대로 읽기도 전에 두려움에 사로잡힐 수 있음
- 추상화를 이해하려면, 예제를 살펴보는 것이 좋음
- 요소를 사용하는 방법을 보여 주는 단위 테스트와 문서의 예제는 추상화가 어떻게 사용도되는지 확실하게 보여 줌
- 극단적인 것은 언제나좋지 않음. 최상의 답은 언제나그사이 어딘가
- 팀의크기
- 팀의 경험
- 프로젝트의크기
- 특징 세트(featureset)
- 도메인 지식
- 많은 개발자가 참여하는 프로젝트는 이후에 객체 생성과 사용 방법을 변경 하기 어렵기 떄문에 추상화 방법을 사용하는 것이 좋음. 최대한 모듈과 부분(part)을 분리하는 것이 좋음.
- 의존성 주입 프레임워크를 사용하면, 클래스 등은 한번만 정의하면 되기 때문에 생성이 얼마나 복잡한지는 신경 쓰지 않아도 됨
- 테스트를 하거나, 다론 애플리케이션을 기반으로 새로운 애플리케이션을 만든다면 추상화를 사용하는 것이 좋음.
- 프로젝트가 작고 실험적 이라면, 추상화를 하지 않고도 직접 변경해도 괜찮음. 문제가 발생했다면, 최대한 빨리 직접 변경하면 됨
- 추상화는 단순하게 중복성을 제거해서 코드를 구성하기 위한 것이 아님
- 추상화는 코드를 변경해야 할 때 도움이 되므로 추상화를 사용하는 것은 굉장히 어렵지만, 이를 배우고 이해해야 함.
- 추상적인 구조를 사용하면, 결과를 이해하기 어렵려움. 추상화를 사용할 때의 장점과 단점을 모두 이해하고, 프로젝트 내에서 그 균형을 찾아야 함