함수의 경우는 기존의 함수에서 새로운 함수를 호출하는 방식으로 리팩토링의 과정을 간소화할 수 있지만, 데이터의 경우는 다르다. 이 데이터가 사용되는 모든 곳에서 한 번에 변경을 해줘야 하기 때문에, 책에서는 데이터를 변경하는 것을 함수로 캡슐화하는 방식으로 리팩토링을 하고 있다. 말은 장황한데 실제 코드로 보면 모두 알 수 있는 기법일 것이다. 아래 코드를 확인해보자.
before
let defaultOwner = {
firstName: "martin",
lastName: "faula",
};
const spaceship = {};
spaceship.owner = defaultOwner;
defaultOwner = {
firstName: "leveca",
lastName: "pasn",
};
after
// 변수 캡슐화하기
// 가변데이터의 경우는 모든 곳에서 한 번에 바꿔줘야 하기 때문에
// 리팩토링의 난이도가 상당히 어렵다.
// 접근할 수 있는 가시성을 함수로 제한한다.
let defaultOwner = {
firstName: "martin",
lastName: "faula",
};
class Person {
constructor(data) {
this._firstname = data.firstName;
this._lastname = data.lastName;
}
get lastName() {
return this._lastname;
}
get firstName() {
return this._firstname;
}
}
function getDefaultOwner() {
return (
defaultOwner || Object.assign({}, defaultOwner) || new Person(defaultOwner)
);
// 1. 가변데이터의 훼손을 막기위해 객체를 복사하거나
// 2. 레코드 캡슐화를 활용해서 대입 연산을 무시한다.
}
function setDefaultOwner(arg) {
defaultOwner = arg;
}
const spaceship = {};
spaceship.owner = getDefaultOwner();
setDefaultOwner({
firstName: "leveca",
lastName: "pasn",
});
const owner1 = getDefaultOwner();
module.exports = {};
확실히 데이터를 다룰때는 원본 데이터를 보호하는 방식을 활용하는 것 같다. 복사한 객체를 반환하거나, 클래스를 활용해서 레코드를 캡슐화하는 방법도 알아보았다. 이렇게 하면 변수를 캡슐화해 외부로 부터 보호하기도 하고 가시성을 줄일 수 있기 때문에 유지보수하는 데에도 많은 도움이 될 것이다.
Refactoring: Improving the Design of Existing Code (2nd Edition) p188-193.