본문 바로가기
책/이펙티브 코틀린

2부 코드설계 > 6장 클래스 설계 > data, sealed, abstract 한정자 / 함수타입 / 태그클래스

by 정선한 2022. 9. 2.
728x90
반응형
2부 코드설계 > 6장 클래스 설계 > 데이터 집합 표현에 data한정자를 사용하라
2부 코드설계 > 6장 클래스 설계 > 연산 또는 액션을 전달할 때는 인터페이스 대신 함수타입을 사용하라
2부 코드설계 > 6장 클래스 설계 > 태그 클래스 보다는 클래스 계층을 사용하라
 
오늘의 TIL 3줄 요약
  • data 한정자, 데이터 클래스의 장점
  • 함수타입으로 얻는 코드의 자유
  • 태그 클래스 vs. 클래스 계층 (sealed, abstract한정자)

1. 책에서 기억하고 싶은 내용

data 한정자, 데이터들을 한꺼번에 전달해야 할 때 사용하는 클래스에 붙어있는 것을 확인할 수 있다. 이 한정자를 붙이면 아래의 함수들이 자동으로 생성된다.
- toString :  로그 출력 및 디버그 시 활용
- equals, hashCode
- copy : immuatable 데이터 클래스를 만들 때 편리, 기본 생성자 프로퍼티가 같은 새로운 객체를 복제
- componentN : 위치를 기반으로 객체를 해제 (위치를 잘못 지정하여 해제할 때, 다양한 문제가 발생할 수 있음)

코틀린의 튜플인 Pair, Triple : 튜플은 Serializable기반으로 생성되어 toString을 사용할 수 있는 제네릭 데이터 클래스이다.

튜플을 사용하는 경우
- 값에 간단하게 이름을 붙일 때
- 표준 라이브러리에서 볼 수 있는 것처럼 미리 알 수 없는 aggregate를 표현할 때
이 경우들을 제외하고는 무조건 데이터 클래스를 사용하는 것이 좋다.

데이터 클래스의 장점
- 함수의 리턴 타입이 더 명확해 진다.
- 리턴 타입이 더 짧아지며, 전달하기 쉬워진다.
- 사용자가 데이터 클래스에 적혀 있는 것과 다른 이름을 활용해 변수를 해제하면, 경고가 출력된다.
데이터 클래스는 코틀린에서 큰 비용 없이 사용할 수 있는 좋은 도구이므로 적극적으로 활용할 것.

대부분의 프로그래밍 언어에는 함수 타입의 개념이 없어 SAM 인터페이스를 활용한다.
SAM Interface : Single-Abstract Method Interface (연산 또는 액션을 전달할 때 메서드가 하나만 존재하는 인터페이스)

함수 타입으로 얻는 코드의 자유
- 람다 표현식 또는 익명 함수로 전달
  - 람다 표현식 사용 시 destructure argument도 사용 가능
- 함수 레퍼런스 또는 제한된 함수 레퍼런스로 전달
- 선언된 함수 타입을 구현한 객체로 전달
- 타입 별칭을 통해 함수 타입도 이름을 붙일 수 있다.

SAM을 사용해야 하는 경우, 코틀린이 아닌 다른 언어에서 사용할 클래스를 설계할 때.
java에서는 인터페이스가 더 명확하기 때문에 함수 타입으로 만들어진 클래스는 자바에서 타입 별칭과 IDE의 지원을 제대로 받을 수 없다.

상수(constant) 모드를 태그라고 부그로 이러한 태그를 포함한 클래스를 태그 클래스라고 함.
태그 클래스의 문제
- 서로 다른 책임을 한 클래스에 태그로 구분해서 넣는다는 것에서부터 시작한다.
- 한 클래스에 여러 모드를 처리하기 위한 상용구가 추가된다.
- 여러 목적으로 사용해야 하므로 프로퍼티가 일관적이지 않게 사용되고 더 많은 프로퍼티가 필요하다.
- 요소가 여러 목적을 가지고, 여러 방법으로 설정할 수 있는 경우에는 상태의 일관성과 정확성을 지키기 어렵다.
- 팩토리 메서드를 사용해야 하는 경우가 많다.

그래서 일반적으로 sealed 클래스를 많이 사용한다.
한 클래스에 여러 모드를 만드는 방법 대신에, 각각의 모드를 여러 클래스로 만들고 타입 시스템과 다형성을 활용.

sealed 한정자
- 외부 파일에서 추가적인 서브 클래스를 만드는 행위 자체를 제한한다.
- 외부에서 추가적인 서브 클래스를 만들 수 없으므로, 타입이 추가되지 않을 것이 보장된다.
- when절에서 else를 따로 만들 필요가 없다.
- 클래스의 서브 클래스를 제어하기 위해서는 sealed 한정자를 사용한다.

abstract 한정자
- 다른 개발자가 새로운 인스턴스를 만들어서 사용할 수 있다.
- 계층에 새로운 클래스가 추가될 수 있는 여지를 남기기 때문에 상속과 관련된 설계를 할 때 사용한다.

상태 패턴(status pattern)
- 객체의 내부 상태가 변화할 때, 객체의 동작이 변하는 소프트웨어 디자인 패턴.
- 프론트엔트 컨트롤러, 프레젠터, 뷰 모델을 설계할 때 많이 사용된다.
- 상태 패턴을 사용하여 프로젝트에 적용 시 서로 다른 상태를 나타내는 클래스 계층구조를 만들게 되며, 현재 상태를 나타내기 위한 읽고 쓸 수 있는 프로퍼티도 만들게 된다. 따라서 상태는 더 많은 책임을 가진 큰 클래스이며 변경될 수 있다.
- (타입 계층) 태그 클래스보다는 sealed 클래스 계층으로 만들어지며, 이를 immutable 객체로 만들고 변경해야 할 때마다, state 프로퍼티를 변경하며 view에서 해당 변화를 observe 하도록 한다.

코틀린에서는 태그 클래스보다 타입 계층을 사용하는 것이 더 좋고 이러한 타입 계층은 sealed 클래스를 사용한다. 이 것은 상태 패턴과는 다르므로 구별은 해야 한다. 타입 계층과 상태 패턴은 실질적으로 함께 사용되는 협력 관계에 있다.

728x90
반응형