개요
객체를 다른 객체에 중첩하면 내부 객체를 참조 혹은 값으로 취급할 수 있다.
참조, 값 차이는 다음과 같다.
참조로 다루는 경우는 내부 객체는 그대로 둔 채 그 객체 속성만 갱신한다.
값으로 다루는 겨우는 새로운 속성을 담은 객체로 기존 객체를 대체한다.
필드를 값으로 다루고 싶다면 내부 객체의 클래스를 수정하여 값 객체로 만들면 된다.
값 객체는 불변이기에 자유롭게 활용할 수 있다.
불변이라면 외부로 그 값을 내줘도 나 몰래 값이 변경되어 내부에 영향 받을 걱정이 없다.
이 특징은 특히 분산 시스템과 동시성 시스템에서 유용하다.
예시
//아직 전화번호가 올바로 설정되지 못하게 짜여 있다고 가정 class Person{ constructor(){ this._telephoneNumber = new TelephoneNumber(); } get officeAreaCode(){return this._telephoneNumber.areaCode;} set officeAreaCode(arg){this._telephoneNumber.areaCode = arg;} get officeNumber(){return this._telephoneNumber.officeNumber;} set officeNumber(arg){this._telephoneNumber.officeNumber = arg;} } class TelephoneNumber{ get areaCode(){return this._areaCode;} set areaCode(arg){this._areaCode = arg;} get number(){return this._number;} set number(arg){this._number = arg;} } |
class TelephoneNumber{ //불변으로 만들기 위해 세터 제거 후 생성자로만 받는다. constructor(areaCode, number){ this._areaCode = areaCode; this._number = number; } get areaCode(){return this._areaCode;} get number(){return this._number;} } |
class Person{ constructor(areaCode,officeNumber){ this._telephoneNumber = new TelephoneNumber(); } get officeAreaCode(){return this._telephoneNumber.areaCode;} //값을 설정할 때 마다 매번 새로운 객체를 리턴한다. set officeAreaCode(arg){this._telephoneNumber = new TelephoneNumber(arg, this.officeNumber);} get officeNumber(){return this._telephoneNumber.officeNumber;} set officeNumber(arg){this._telephoneNumber = new TelephoneNumber(this.officeAreaCode,arg);} } |
이제 전화번호 클래스는 불변 클래스이다. 이제 논리적 동치성을 위해 값 기반 비교를 해야한다. 자바스크립트는 참조 기반 동치성을 값 기반 동치성으로 대체하는 메서드가 없다. 그냥 equals()함수를 직접 만든다. |
class TelephoneNumber{ constructor(areaCode,officeNumber){ this._areaCode = areaCode; this._officeNumber = officeNumber; } get areaCode(){return this._areaCode;} set areaCode(arg){this._areaCode = arg;} get number(){return this._number;} set number(arg){this._number = arg;} //논리적 동치성 검사 메서드 equals(other){ if(!(other instanceof TelephoneNumber)) return false; return Object.keys(this).every(a=>this[a] === other[a]); } } |
class TelephoneNumber{ constructor(areaCode, number){ this._areaCode = areaCode; this._number = number; } get areaCode(){return this._areaCode;} get number(){return this._number;} //논리적 동치성 검사 메서드 equals(other){ if(!(other instanceof TelephoneNumber)) return false; return Object.keys(this).every(a=>this[a] === other[a]); } } |
class Person{ constructor(){ this._telephoneNumber = new TelephoneNumber(); } get officeAreaCode(){return this._telephoneNumber.areaCode;} set officeAreaCode(arg){this._telephoneNumber = new TelephoneNumber(areaCode, this.officeNumber);} get officeNumber(){return this._telephoneNumber.officeNumber;} set officeNumber(arg){this._telephoneNumber = new TelephoneNumber(this.officeAreaCode, arg);} } class TelephoneNumber{ constructor(areaCode, number){ this._areaCode = areaCode; this._number = number; } get areaCode(){return this._areaCode;} get number(){return this._number;} //논리적 동치성 검사 메서드 equals(other){ if(!(other instanceof TelephoneNumber)) return false; return Object.keys(this).every(a=>this[a] === other[a]); } } const t1 = new TelephoneNumber("12345","67890"); const t2 = new TelephoneNumber("12345","67890"); console.log(t1.equals(t2)); |
'IT책, 강의 > 리팩터링' 카테고리의 다른 글
09 - 데이터 조직화 - 매직 리터럴 바꾸기 (0) | 2023.09.04 |
---|---|
09 - 데이터 조직화 - 값을 참조로 바꾸기 (0) | 2023.09.03 |
09 - 데이터 조직화 - 파생 변수를 질의 함수로 바꾸기 (0) | 2023.08.27 |
09 - 데이터 조직화 - 파생 변수를 질의 함수로 바꾸기 (0) | 2023.08.24 |
09 - 데이터 조직화 - 필드 이름 바꾸기 (0) | 2023.08.19 |