OOP(Object Oriented Programming) JS 21.04.10
in Dev on Java Script
OOP(Object Oriented Programming) : 객체 지향 언어
객체 지향 프로그래밍은 단순히 별개의 변수와 함수로 순차적(위에서 부터 아래로)으로 작동하는 것을 넘어, 데이터의 접근과, 데이터의 처리 과정에 대한 모형을 만들어 내는 방식을 고안. 따라서, 데이터와 기능이 별개로 취급되지 않고, 한번에 묶어서 처리 가능.(자바스크립트는 엄밀히 말해 객체 지향 언어는 아니지만, 객체 지향 패턴으로 작성 가능)
즉, OOP는 프로그램 설계 철학이며 OOP의 모든 것은 “객체”로 그룹화된다.
class & constructor & instance
클래스(class) : 일종의 원형(original form)으로, 객체를 생성하기 위한 청사진, 설계도, 형식, 틀. 클래스는 객체 instance를 만들기 위한 생성자(constructor) 함수를 포함.
인스턴스(instance) : 클래스로 만들어진 사례(instance).
생성자 함수(constructor) : 클래스를 이용해 인스턴스를 생성 할 때 인스턴스의 특징을 정할 수 있는 함수. (클래스 내부에 있다.)
// 클래스
class Car {
// 생성자 함수
constructor (brand, color, price) {
// this는 인스턴스를 참조.
this.brand = brand;
this.color = color;
this.price = price;
}
// method 함수.
howMuch() {
// 파미터에는 반드시 this를 붙여줘야한다.
return `${this.color}색 ${this.brand}의 가격은 ${this.price}원 입니다.`
}
}
// class(=car)를 사용하여 instance(=firstcar) 생성.
let firstCar = new Car ('테슬라', '하얀', '1억');
// method 사용
firstCar.howMuch();
// "하얀색 테슬라의 가격은 1억원 입니다."
OOP의 4가지 주요 개념
이 4가지 개념을 통해 재사용성 획득.
Encapsulation (캡슐화)
- 데이터(속성)와 기능(메소드)을 하나의 단위로 묶는 것
- 은닉(hiding): 구현은 숨기고, 동작은 노출시킴
- 느슨한 결합(Loose Coupling)에 유리: 언제든 구현을 수정할 수 있음. 절차적 코드(위에서 부터 아래로 순차적 진행)의 경우 데이터 형태가 바뀔 때 코드의 흐름에 큰 영향을 미치지만 OOP의 경우 객체 내 메소드만 수정하고 코드의 전체적인 흐름은 바뀌지 않도록 할 수 있다.
Abstraction (추상화)
내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만든다는 개념. 캡슐화가 코드나 데이터의 은닉에 포커스가 맞춰져있다면, 추상화는 클래스를 사용하는 사람이 필요하지 않은 메소드 등을 노출시키지 않고, 기능 단순한 이름으로 정의하는 것에 포커스가 맞춰져 있습니다. 추상화의 본질 : 클래스 정의 시, 메소드와 속성만 정의한 것을 인터페이스.
Inheritance (상속)
상속은 부모 클래스의 특징을 자식 클래스가 물려받는 것입니다. “기본 클래스(base class)의 특징을 파생 클래스(derive class)가 상속받는다”
Polymorphism (다형성)
“다양한 형태”를 가질 수 있다는 말. 하나의 기본 함수를 만들고 그걸 상황에 맞게 변경할 수 있다는 뜻.
만약 다형성이 없다면, 기본(부모) 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 할 것.
if (type === 'select') {
renderSelect()
}
else if (type === 'text') {
renderTextBox()
}
else if (type === 'checkbox') {
renderCheckBox()
}
//...
예시 코드 : 클로저 모듈 패턴 vs Class
- 클로저 모듈 패턴
// 캡슐화 : 데이터와 함수를 하나의 단위로 묶음
function makeCounter() {
let value = 0;
// return 값에 함수가 있으므로 외부에서 이 함수들에 다이렉트로 접근 할 수 없다.
// console.log(increase, decrease, getValue)
// increase is not defined.
return {
increase: function() {
value++
},
decrease: function() {
value--
},
getValue: function() {
return value;
}
}
}
// 다형성 : 위 함수를 다양하게 사용 가능
let counter1 = makeCounter();
counter1.increase();
counter1.getValue(); // 1
let counter2 = makeCounter();
counter2.decrease();
counter2.getValue(); // -1
위 코드를 class로
class Counter {
constructor() {
this.value = 0;
}
increase() {
this.value++;
}
decrease() {
this.value--;
}
getValue() {
return this.value;
}
}
let counter1 = new Counter()
counter1.increase()
counter1.getValue() // 1
counter1.value // 인스턴스에 직접 접근가능
let counter2 = new Counter()
counter2.decrease()
counter2.getValue() // -2
counter2.value // 인스턴스에 직접 접근가능