상세 컨텐츠

본문 제목

6.6. 변수 캡슐화하기 (Encapsulate Variable)

🍜개발자라면/책을 읽자✍

by :Eundms 2021. 9. 26. 14:58

본문

- 접근할 수 있는 범위가 넓은 데이터를 옮길 때 

: 그 데이터로의 접근을 독점하는 함수를 만드는 식으로 캡슐화하는 것이 가장 좋은 방법

- 데이터 변경 전 검증이나 변경 후 추가 로직을 쉽게 끼워 넣을 수 있음.

: 객체 지향에서 객체의 데이터를 private로 유지해야 한다고 강조하는 이유

= 데이터 변경 통로가 정해지게 됨. 오류 찾기 쉬움

- 클래스 쪼개기 전, 필드를 자가 캡슐화


방법

1. 변수로의 접근과 갱신을 전담하는 캡슐화 함수들을 만든다.

2. 정적 검사를 수행한다.

3. 변수를 직접참조하던 부분을 모두 적절한 캡슐화 함수 호출로 바꾼다. 하나씩 바꿀 때마다 테스트한다.

4. 변수의 접근 범위를 제한한다.

-> 변수로의 직접 접근을 막을 수 없을 때도 있다. 그럴 때는 변수 이름을 바꿔서 테스트해보면 해당 변수를 참조하는 곳을 쉽게 찾아낼 수 있다. // 무슨 말일까

5. 테스트한다.

6. 변수 값이 레코드라면 레코드 캡슐화하기를 적용할지 고려해본다.

 


  전역 변수  

전역 변수에 중요한 데이터가 담겨 있다

// 변경 이전
let defaultOwner = {firstName: "마틴", lastName: "파울러"};
// 참조
spaceship.owner = defaultOwner;
// 갱신
defaultOwner = {firstName :"레베카", lastName:"파슨스"};

 

getter, setter 생성 &  접근자만 노출시키기
// 1) getter, setter 생성
function getDefaultOwner(){
    return defaultOwner;
}
function setDefaultOwner(arg){
    defaultOwner = arg;
}

// 2) getter, setter로 변경 이전 코드를 바꾼다.
spaceship.owner = getDefaultOwner();
setDefaultOwner({firstName:"레베카",lastName:"파슨스"});

// 3) 접근자만 노출 시키기
let defaultOwner = {firstName: "마틴", lastName: "파울러"};
export function getDefaultOwner(){
    return defaultOwner;
}
export function setDefaultOwner(arg){
    defaultOwner = arg;
}

> 자바스크립트에서는 게터와 세터의 이름을 똑같이 짓고 인수 여부에 따라 구분하는 방식을 많이 사용한다. (get,set)


  필드값 변경 제어 

1. 게터로 값을 반환할 때, 데이터의 복제본을 반환하도록 한다.
let defaultOwnerData = {firstName: "마틴", lastName: "파울러"};
export function defaultOwner(){
    return Object.assign({},defaultOwnerData);
}
export function setDefaultOwner(arg){
    defaultOwnerData = arg;
}

원본을 변경하기를 원하는 클라이언트가 있다면...?
2. 레코드 캡슐화하기

> 원본으로의 링크를 유지해야 할 때

let defaultOwnerData = {firstName: "마틴", lastName: "파울러"};
export function defaultOwner(){
    return new Person(defaultOwnerData);
}
export function setDefaultOwner(arg){
    defaultOwnerData = arg;
}
class Person {
    constructor(data){
        this._lastName = data.lastName;
        this._lastName = data.firstName;
    }
    get lastName() {return this._lastName;}
    get firstName() {return this._firstName;}
}

 

위 방법 모두 깊이가 1일 때만 가능하다

 

관련글 더보기

댓글 영역