본문 바로가기
My Wiki (CodesStates)/JS,Node

(5-1) JS/객체 지향 JavaScript/클래스를 이용한 모듈화

by Esoolgnah 2021. 8. 23.
728x90

 

객체 지향 프로그래밍(OOP, Object-oriented programming)

절차 지향 프로그래밍과는 다르게 데이터와 기능을 한 곳에 묶어서 처리한다. 속성과 메소드가 하나의 "객체"라는 개념에 포함되며, 이는 자바스크립트 내장 타입인 object(이하, object literal)와는 다르게 클래스(Class)라는 이름으로 부른다. 객체 지향 프로그래밍은 사람이 세계를 보고 이해하는 방법과 매우 흡사하다. 코드를 추상화하여 직관적으로 생각할 수 있기 때문에 이미 오래 전부터 프로그래밍 방법론으로 매우 빠르게 적용되었다. 객체 지향 프로그래밍을 철저하게 적용한 프로그래밍 언어 Java나 C#과는 다르게 자바스크립트에서 OOP를 구현하는 방법은 조금 독특하다.

 

 

클래스와 인스턴스

객체 지향 프로그래밍의 기초가 되는 용어부터 설명하겠다. 객체 지향 프로그래밍은 하나의 모델이 되는 청사진(blueprint)을 만들고 그 청사진을 바탕으로 한 객체를 만드는 프로그래밍 패턴이다. 앞서 언급된 청사진은 자동차 생산을 위한 설계도에 비유된다. 자동차가 기능하기 위해서는 네 바퀴와 핸들, 좌석 그리고 엔진이 필요할 것이다. 이러한 기본적인 설계는 차의 종류에 상관없이 대체적으로 동일하게 적용된다. 이런 설계도(청사진)를 바탕으로 각각의 객체가 특정한 자동차 모델로 나오게 되는 것이다.

 

 

 

 

사실, 이미 자바스크립트에는 "객체"라는 개념이 객체 지향 프로그래밍과 무관하게 이미 존재한다. 따라서 여기서는 용어를 잘 구분하는 것이 중요하다. 앞으로 그냥 객체가 아닌 "청사진"을 바탕으로 한 객체는 인스턴스 객체(instance object), 줄여서 인스턴스(instance)라고 부르겠다. 청사진은 클래스(class)라고 부르도록 하자.

 

 

 

 

객체를 어떤 식으로 만드는지 살펴보면, 그냥 일반적인 함수를 정의하듯 만든다. 이때 함수를 이용하는 방법이 조금 다르다. 그냥 실행하는 것이 아니고 new 키워드를 써서 만든다. 이는 새로운 인스턴스를 만드는 방법이다. 클래스를 그냥 함수로 정의하면 일반적인 다른 함수와 어떻게 구분할까? 클래스를 만드는 암묵적인 규칙으로 보통 클래스는 대문자, 그리고 일반명사로 만든다. 따라서 일반적인 함수를 만들 때에는 적절한 동사를 포함하고 소문자로 시작하도록 만들면 좋다.

 

 

 

 

그리고 클래스를 만드는 새로운 문법이 ES6(ECMAScript 6, 비교적 최근 자바스크립트 문법입니다)에 도입되었다. 바로 class 키워드이다. 최근에는 ES6 방법을 주로 사용한다. 여기서 보이는 함수는 객체지향 프로그래밍에서 생성자(constructor) 함수라고 부른다. 인스턴스가 만들어질 때 실행되는 코드이다. 참고로, 생성자 함수는 return값을 만들지 않는다.

 

 

 

 

인스턴스를 만들 때에는 new 키워드를 사용한다. 즉시 생성자 함수가 실행되며 변수에 클래스의 설계를 꼭 닮은 새로운 객체, 즉 인스턴스가 할당된다. 각각의 인스턴스는 클래스의 고유한 속성과 메소드를 갖게 된다.

 

 

 

 

속성과 메소드란 용어가 낯설게 느껴지겠지만 현실 세계를 생각해보면 조금 더 쉽게 와닿는다. 예를 들어 자동차의 속성은 브랜드, 차 이름, 색상, 현재 연료 상태, 최고 속력 등이 있을 수 있다. 메소드는 쉽게 말해 "객체에 딸린 함수"이다. 연료 주입, 속력 설정, 운전 등이 메소드이다. * 잠깐 다음 슬라이드로 가기 전에, "학생"이라는 클래스를 만든다고 상상해보자. 속성과 메소드는 각각 어떤 것들이 있을까?

 

 

 

 

this라는 새로운 키워드가 등장한다. 객체지향 프로그래밍에서는 빠지지 않고 등장하므로 간단하게 알아두자. 한마디로 this는 인스턴스 객체를 의미한다. parameter로 넘어온 브랜드, 이름, 색상 등은 인스턴스 생성시 지정하는 값이며 위와 같이 this에 할당한다는 것은, 만들어진 인스턴스에 해당 브랜드, 이름, 색상을 부여하겠다는 의미이다.

 

 

 

 

이번엔 메소드 정의이다. ES5는 prototype이라는 키워드를 사용해야 메소드를 정의할 수 있다. Car 클래스에 메소드를 추가하기 위해서는 `Car.prototype.refuel`과 같이 `prototype`을 이용해야 한다. 이후 `prototype`에 대해서 자세히 공부하고 지금은 메소드 정의 시 사용법만 숙지하자. ES6에서는 생성자 함수와 함께 class 키워드 안쪽에 묶어서 정의한다. `refuel() {}`, drive() {}`와 같이 작성되어 있는 부분이다.

 

 

 

 

 

 

방금 설정한 속성과 메소드를 어떻게 인스턴스에서 사용하는 지 아는 것이 더 중요하다. 이 코드를 실습할 때에 한번씩 인스턴스 (avante, mini 등)를 console.log로 살펴보자.

 

 

 

 

낯선 용어가 많이 등장했다. 여기에 있는 용어는 오직 자바스크립트에서만 유효한 용어이다. 생성자 함수 정도만 객체 지향 프로그래밍에서 보편적인 개념이며 prototype이나 this는 취업을 위해서라면 언젠가는 알아야 할 것들이지만 지금은 당장 개념에 너무 매이지 말고, 코드상에서 어떻게 쓰이는 지만 알아도 좋다.

 

 

 

 

이 그림을 눈에 담아두고, 외워두자. 용어를 알아두어야 이후 설명을 들을 때에 뭐가 뭔지 헷갈리지 않게 된다. 이 그림에서는 ES5 방식을 보여주고 있지만 ES6 방식이 더욱 많이 쓰이기에 위에 안내한 코드를 ES6로 반드시 직접 작성해보자.

 

 

 

 

자, 그럼 클래스의 유용한 예제를 좀 살펴보자. 사실 여러분들은 이런 객체지향적인 방법을 이미 사용하고 있었다. 바로 우리가 그동안 만들었던 배열은, 전부 (대문자) Array의 인스턴스이다. 먼저 코드를 한번 살펴보자. 속성이나 메소드 사용법이 흡사할 것이다.

 

 

 

 

앞서 말했다시피 배열은 (대문자) Array의 인스턴스이다. 따라서 new Array(__, ___, ___) 와 같은 방식으로도 배열을 만들 수 있다.

 

 

 

 

살짝만 더 깊게 들어가보면 여러분이 배열 메소드 (push, filter, forEach...)등을 배울 때에 mdn 문서를 유심히 살펴보신 분들은 메소드들이 대부분 Array.prototype.메소드명 과 같이 안내되어 있음을 발견하셨을 것이다. 이는 모든 메소드들이 클래스의 원형 객체(prototype)에 정의되어 있기 때문이다. 자세한 내용은 prototype을 학습할 때에 다루겠다.

 

 

 

 

클래스 문법을 이용하여 카운터를 만드는 실습을 해 보자.

 

class Counter {
  constructor() {
    this.value = 0; // 생성자 호출을 할 경우, this는 new 키워드로 생성한 Counter의 인스턴스이다
  }
  increase() {
    this.value++
  }
  decrease() {
    this.value--
  }
  getValue() {
    return this.value
  }
}

let counter1 = new Counter() // 생성자 호출
counter1.increase()
counter1.getValue() // 1

[코드] OOP 패턴으로 구현한 counter 예시

 

 

 

 

반응형

댓글