본문 바로가기

프로그래밍 공부/JavaScript

JavaScript - 캡슐화

캡슐화는 잘못 사용될 수 있는 객체의 특정 부분을 사용자가 사용할 수 없게 막는 기술이다. 

생성자 함수를 이용한 사각형의 넓이를 구하는 코드

function Rectangle(widthheight){
     this.width=width;
     this.height=height;
}

Rectangle.prototype.getArea=function(){
     return this.width*this.height;
}

let rectangle = new Rectangle(5,7);
alert('넓이 : '+rectangle.getArea());

위에 경우는 실행할때는 문제가 없지만, 길이에 음수를 넣을 수 있다. 제작자는 당연히 길이에 음수가 들어갈 수 없다는 것을 알고 있지만 사용자들 중에는 넣을 수 있기 때문이다. 위의 설명에 있듯이 캡슐화는 이렇게 객체의 특정 부분을 사용자가 사용할 수 없게 막는 것이다. 자바스크립트에서 캡슐화를 구현할 때는 클로저를 활용한다.

프로토타입, 게터와 세터를 이용한 사각형 넓이를 구하는 코드

function Rectangle(wh){
// 변수 선언
     let _width=w;
     let _height=h;

// 메서드 선언
     this.getWidth=function(){
          return this._width;
     }
     this.getHeight=function(){
          return this._height;
     }
     this.setWidth=function(value){
          if(value<=0){
               return alert('음수를 넣을 수 없습니다.');
          }
          return this._width=value;
     }
     this.setHeight=function(value){
          if(value<=0){
               return alert('음수를 넣을 수 없습니다.');
          }
          return this._height=value;
     }
}

// 입출력 코드
Rectangle.prototype.getArea=function(){
     return this.getWidth()*this.getHeight();
}

let
 rectangle=new Rectangle();
rectangle.setWidth(Number(prompt('가로길이 입력')));
rectangle.setHeight(Number(prompt('세로길이 입력')));

alert('넓이 : '+rectangle.getArea());

생성자 함수 안에서 width와 height를 변수로 선언했다, 이후에는 외부에서 지역변수가 된 width와 height를 사용할 수 없고 오직 get메서드() 형태와 set메서드() 형태의 메서드를 사용해야 한다. 이전에도 get메서드() 형태와 set메서드() 형태를 사용한 적이 있는데, 위의 코드에는 setWidth()나 setHeight()에 매개변수로 입력받은 값이 0이하가 되면 alert() 로 경고가 반환되게 조건문을 사용했다.

따라서 위의 코드의 입출력 부분에 입력한 rectangle.setWidth()와 rectangle.setHeight()에 음수를 넣으면 조건문으로 인해 alert()가 실행이 되므로 width와 height 속성에 음수가 들어가는 일은 없어진다. 위의 코드도 문제점이 하나 있는데, 그것은 프로토타입인 메서드가 하나 뿐이고, 그것은 시스템의 메모리를 비효율적으로 낭비하게 된다는 것을 의미한다.

게터와 세터를 생성자 함수의 프로토타입으로 지정한다.

function Rectangle(wh){
     this._width=w;
     this._height=h;
}
Rectangle.prototype.getWidth=function(){
     return this._width;
}
Rectangle.prototype.getHeight=function(){
     return this._height;
}
Rectangle.prototype.setWidth=function(value){
     if(value<=0){
          return alert('음수를 넣을 수 없습니다.');
     }
     
return this._width=value;
}
Rectangle.prototype.setHeight=function(value){
     
if(value<=0){
          
return alert('음수를 넣을 수 없습니다.');
     
}
     
return this._height=value;
}
Rectangle.prototype.getArea=function(){
     
return this._width*this._height;
}

let rectangle=new Rectangle();
rectangle.setWidth(Number(prompt('가로길이 입력')));
rectangle.setHeight(Number(prompt('세로길이 입력')));

alert('넓이 : '+rectangle.getArea());

클래스에 경우에는 게터와 세터의 사용방법이 조금 다르다.

클래스, 게터와 세터를 사용하는 방법

class Rectangle{
     constructor(wh){
         this._width=w;
         this._height=h;
}

// width의 게터와 세터
     get width(){
          return this._width;
     }
     set width(value){
          if(value<=0){
               return alert('음수를 넣을 수 없습니다.');
          }
          this._height=value;
     }

// height의 게터와 세터
     get height(){
          return this._height;
     }
     set height(value){
          if(value<=0){
               return alert('음수를 넣을 수 없습니다.');
          }
          this._width=value;
     }

// 넓이는 구하는 코드
     getArea(){
          return this._width*this._height;
     }
}

// 입출력 코드
const rectangle=new Rectangle();

rectangle.width=Number(prompt('가로길이 입력'));
rectangle.height=Number(prompt('세로길이 입력'));

alert('넓이 : '+rectangle.getArea());

자바스크립트의 클래스는 변수를 숨길 수 없다, 그래서 일반적으로 변수 앞에 _를 붙이는데, 이건 주로 개발자 본인 외에는 만지지 말라는 표시이다. 클래스에서 게터와 세터는 메서드를 선언할때 앞에 get 또는 set을 붙여서 선언하게 된다. get은 '값을 가져오는 동작'을 할때 set은 '값을 넣는 동작'을 할때 각각 자동으로 호출이 된다.

캡슐화.html
0.00MB

'프로그래밍 공부 > JavaScript' 카테고리의 다른 글

JavaScript - 생성자 함수 연습문제  (0) 2019.12.10
JavaScript - 상속  (0) 2019.12.10
JavaScript - 계산기  (0) 2019.12.10
JavaScript - 클래스  (0) 2019.12.09
JavaScript - 프로토타입  (0) 2019.12.09