Encapsulation and Least Exposure
캡슐화는 종종 OOP의 원리로 인용된다. 하지만 이 개념은 더 포괄적인 영역을 맡고 있고, 최근 컴포넌트 기반 아키텍처의 어플리케이션을 설계하는 프론트 엔드 개발 영역에 이끄는 트렌드로 작용하고 있다. 캡슐화를 이용하는 가장 큰 목적은 데이터와 기능의 가시성을 통제하는 데에 있다. 이는 이전 챕터에서 다루었던 '노출의 최소화'의 관점과 같은 맥락을 유지하고 있고 JS에서는 렉시컬 스코프의 기술을 통해 이 관점을 지키고 있다.
이러한 노력의 자연스러운 결과는 결국 더 나은 코드의 체계화를 지향한다는 것이다. 어떤 경계를 기준으로 무엇이 어디 있는지 쉽게 알 수 있다는 것은 소프트웨어의 유지보수를 더 용이하게 하고 데이터와 기능의 외부 스코프로 무방비한 노출을 예방함으로 안정성을 높일 수 있다.
What Is a Module?
모듈은 관련된 데이터와 기능(메소드)들의 집합이다. 이러한 정보들은 또 private 과 public 의 성격을 띄며 나누어질 수 있다. 모듈이 어떤 것인지 좀 더 자세히 알기 위해, '모듈은 아니지만' 그러한 특성을 띄고 있는 몇몇 코드 패턴을 비교해보자.
Namespaces (Stateless Grouping)
// namespace, not module
var Utils = {
cancelEvt(evt) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
},
wait(ms) {
return new Promise(function c(res){
setTimeout(res,ms);
});
},
isValidEmail(email) {
return /[^@]+@[^@.]+\.[^@.]+/.test(email);
}
};
데이터가 없이 무상태의 함수만을 그룹화 해놓은 이러한 코드 패턴은 'namespace'라고 부르는 게 더 정확하다.
Data Structures (Stateful Grouping)
// data structure, not module
var Student = {
records: [
{ id: 14, name: "Kyle", grade: 86 },
{ id: 73, name: "Suzy", grade: 87 },
{ id: 112, name: "Frank", grade: 75 },
{ id: 6, name: "Sarah", grade: 91 }
],
getName(studentID) {
var student = this.records.find(
student => student.id == studentID
);
return student.name;
}
};
Student.getName(73);
// Suzy
이 구조는 데이터와 기능을 모두 하나의 스코프로 번들링하고는 있지만, 데이터의 가시성을 통제하지는 못하고 있다. records
가 어디서든 접근 가능하다는 점에서 이 구조는 모듈이라기보다는 하나의 자료 구조에 가까운 형태를 띄고 있다.
Modules (Stateful Access Control)
모듈을 구현하기 위한 조건은 '데이터의 그룹화'와 '가시성의 통제', 총 두가지로 볼 수 있다. 또 모듈을 통해 인스턴스를 하나만 얻을 것인지, 혹은 다수의 인스턴스를 만들어줄 것인지 그 용도에 따라 분류가 가능하다. 한 개의 인스턴스만을 필요로 하는 모듈은 보통 IIFE 를 통해 만들어주게 되는데 이를 'singleton'이라고 한다. 반대로 여러 개의 인스턴스가 필요하다면 그냥 모듈을 함수 형태로 만들고 필요할 때마다 호출 할당을 해주면 된다. 이것은 'module factory'라고도 한다.
classic module로 분류할 수 있는 조건은 다음과 같다.
- 최소 하번은 실행되는 모듈 팩토리 함수로부터, 외부 스코프일 것.
- 모듈의 내부 스코프는 모듈에 대한 상태를 나타내는 숨겨진 정보를 하나라도 갖고 있을 것.
- 모듈은 public API 로 숨겨진 모듈 상태에 대한 함수 참조를 하나라도 반환할 것(클로저 이용).
Exit Scope
모듈의 대해 어떤 포맷을 사용하든 간에, 모듈은 프로그램의 데이터와 기능들을 구조화하고 체계화하는데 가장 효율적인 방법이다. 또한 모듈은 Scope & Closure 파트에서 변수와 함수를 적절한 곳에 위치시키기 위해 렉시컬 스코프를 어떻게 사용해야하는지에 대한 최종 종착지라고 할 수 있다. 왜냐하면 모듈의 방식에서, 우리가 모듈의 state를 유지할 수 있는 이유는 렉시컬 스코프 시스템의 영향을 받은 클로저가 존재하기 때문이다.
'Development' 카테고리의 다른 글
[21.01.19] YDKJSY - this Or That? / this All Makes Sense Now! (1) | 2024.01.07 |
---|---|
[21.01.16] YDKJSY - Appendix A: Exploring Further (1) | 2024.01.07 |
[21.01.11] YDKJSY - Using Closures (1) | 2024.01.07 |
[21.01.08] YDKJSY - The (Not so) Secret Lifecycle of Variables (0) | 2024.01.07 |
[21.01.08] JavaScript this 의 동작 원리 (0) | 2024.01.07 |