😀 책에서 기억하고 싶은 내용을 써보세요.

orders.filter(o => "high" === o.priority
                || "rush" === o.priority);
orders.filter(o => o.priority.higherThan(new Priority("normal")))

 

 

배경

단순한 출력 이상의 기능이 필요해지는 순간 그 데이터를 표현하는 전용 클래스를 정의한다.

시작은 기본형 데이터를 단순히 감싼 것과 큰 차이가 없을 것이라 효과가 미미하다.

하지만 나중에 특별한 동작이 필요해지면 이 클래스에 추가하면 되니 프로그램이 커질수록 점점 유용한 도구가 된다.

 

 

 

절차

  1. 아직 변수를 캡슐화하지 않았다면 캡슐화한다.
  2. 단순한 값 클래스를 만든다. 생성자는 기존 값을 인수로 받아서 저장하고, 이 값을 반환하는 게터를 추가한다.
  3. 정적 검사를 수행한다.
  4. 값 클래스의 인스턴스를 새로 만들어서 필드에 저장하도록 세터를 수정한다. 이미 있다면 필드의 타입을 적절히 변경한다.
  5. 새로 만든 클래스의 게터를 호출한 결과를 반환하도록 게터를 수정한다.
  6. 테스트한다.
  7. 함수 이름을 바꾸면 원본 접근자의 동작을 더 잘 드러낼 수 있는지 검토한다.
    • 참조를 값으로 바꾸거나 값을 참조로 바꾸면 새로 만든 객체의 역할(값 또는 참조 객체)이 더 잘 드러나는지 검토한다.

 

 

예시

레코드 구조에서 데이터를 읽어 들이는 단순한 주문 클래스를 살펴보자.

// Order 클래스
constructor(data) {
	this.priority = data.priority;
	// 나머지 초기화 코드 생략

클라이언트에서는 이 코드를 다음처럼 사용한다.

 

// 클라이언트
highPriorityCount = orders.filter(o => "high" === o.priority
                                    || "rush" === o.priority)
                          .length;

 

1️⃣ 데이터 값을 다루기 전에 항상 변수부터 캡슐화한다.

// Order 클래스
get priority() {return this._priority;}
set priority(aString) {this._priority = aString;}

이제 우선순위 속성을 초기화하는 생성자에서 방금 정의한 세터를 사용할 수 있다.

⇒ 이렇게 필드를 자가 캡슐화하면 필드 이름을 바꿔도 클라이언트 코드는 유지할 수 있다.

 

2️⃣ 우선순위 속성을 표현하는 값 클래스 Priority를 만든다.

⇒ 이 클래스는 표현할 값을 받는 생성자와 그 값을 문자열로 반환하는 변환 함수로 구성된다.

class Priority {
	constructor(value) {this._value = value;}
	toString() {return this._value;}
}

 

4️⃣ 5️⃣ 그런 다음 방금 만든 Priority 클래스를 사용하도록 접근자들을 수정한다.

// Order 클래스
get priority() {return this._priority.toString();}
set priority(aString) {this._priority = new Priority(aString);}

 

7️⃣ 이렇게 Priority 클래스를 만들고 나면 Order 클래스의 게터가 이상해진다. 이 게터가 반환하는 값은 우선순위 자체가 아니라 우선순위를 표현하는 문자열이다. 그러니 즉시 함수 이름을 바꿔준다.

// Order 클래스
get priorityString() {return this._priority.toString();}
set priority(aString) {this._priority = new Priority(aString);}
// 클라이언트
highPriorityCount = orders.filter(o => "high" === o.priorityString
                                    || "rust" === o.priorityString)
                          .length;
  • 지금처럼 매개변수 이름만으로 세터가 받는 데이터의 유형을 쉽게 알 수 있다면 세터의 이름을 그대로 둬도 좋다.

 

 

🤔 오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요.

  • 변수 캡슐화를 먼저 진행하고 그 다음에 컬렉션 캡슐화 진행
    • getter, setter 접근자 메서드 캡슐화를 진행
    • 여기서 한번 더 고려할 것은 세터를 통해 클라이언트 누구든 수정을 가능하게 할 것인지에 대한 것
    • ⇒ 데이터를 수정하거나 추가하는 부분은 한번 더 생각해보고 신중하게 결정

 

🔎 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

  • 캡슐화의 개념을 간결하게 설명한 글은 없을지 찾아보자
    • 캡슐화란 관련 있는 자료, 동작들을 하나로 묶어 요약하고 사용자에게는 배우적인 접근을 허용하지 않는 대신에 사용의 편의성을 제공해주는 것이다.
    • 여러 자료 및 처리과정을 하나의 모듈(부품)처럼 사용하므로 객체간의 이식성이 높아진다.
    • 참고한 링크 ⇒ 링크

 

 

반응형

+ Recent posts