객체 지향 프로그래밍
객체 지향 프로그래밍(OOP, Object-Oriented-Programming)이란, 프로그래밍을 작성하고자하는 일종의 패러다임이다.
지금 우리가 간단한 코드들을 작성할 때 사용하는 방식을 절차적 프로그래밍이라고 한다. 아주 간단한 코드를 짜는 데는 적합하지만 코드가 커지면서 문제점이 발생한다. 과거에 객체 지향 프로그래밍이 없었을 때에도, 개발자들이 코드를 짜면서 프로그램의 덩치가 커지게 되어 여러가지 유지 보수나 관리 상에서의 문제들이 많이 발생하게 되었다.
대표적인 문제점이 바로 변수에 관한 문제이다. 보통 절차적 프로그래밍에서의 변수는 일반적으로 전역 변수로 관리하게 된다. 프로그램이 점점 커질 수록 여러가지의 동작에서 하나의 변수명을 공유해서 쓰는 등의 문제들이 발생하고, 이를 해결하기 위해서 변수명을 파일이나 모듈 단위로 관리하는 개념도 등장했으나, 이는 여전히 복잡한 방식으로 남게 된다.
이 후 문제를 해결하기 위해서 서로 연관이 있는 데이터들을 하나로 묶어, 해당 범위 내에서만 변수에 접근을 할 수 있는 구조체라는 형식이 만들어진다. 그리고 구조체에 쓰이는 함수들까지 하나로 묶어 클래스(Class)라는 것이 탄생하게 되고, 클래스를 통해서 만들어지는 인스턴스를 객체(Object)라고 부르게 된다. 하나의 큰 문제를 해결하는 방식에서, 점차 작은 문제로 쪼개가면서 개발을 관리할 수 있게 된 것이다.
기존의 절차적 프로그래밍에서, 기능을 작은 모듈로 나눠 여러 모듈이 독립적으로 돌아가는 프로그래밍의 형태가 만들어지게 된다. 그러면서 등장한 것이 어떤 사물이나 대상을 하나의 객체로 인식하여, 객체를 만들어내고 객체 간의 상호작용을 이용해 프로그래밍을 하는 패러다임인 객체 지향 프로그래밍이다.
객체 지향 프로그래밍은 일종의 방법론이다. 어떤 문제를 해결할 때, 꼭 객체 지향 프로그래밍으로만 해결할 수 있는 건 아니다. 다만 여러 사람들이 큰 규모의 개발을 안전하고 이해하기 쉽게 하도록 약속된 개념일 뿐이다.
객체 지향 프로그래밍에서는 객체의 재사용성을 높이기 위한 여러 가지 개념들이 있다. 객체 지향의 기본이 되는 개념들인데 캡슐화, 추상화, 상속, 다형성이 대표적이다. 여기서는 자바스크립트와 결합해서 얘기해보려고 한다.
자바스크립트에서의 객체 지향 프로그래밍
자바스크립트에서는 객체 지향 프로그래밍의 개념인 캡슐화/추상화/상속/다형성이라는 개념을 다 구현할 수는 없다.
자바스크립트에도 class라는 개념이 존재하나, 이는 객체 지향 프로그래밍 언어에서의 class 문법과는 조금 다르다.
보통 자바스크립트에서 객체를 생성할 때는, 생성자 함수를 생성하게 된다. 또는 class를 쓸 수도 있다.
class는 사실 생성자 함수의 문법을 조금 간단하게 바꾸어 놓은 것에 불과하다. 그래서 클래스/생성자 함수는 사실상 크게 다르지 않다고 보면 된다.
생성자 함수/클래스 이외에도, 팩토리 함수를 통해 객체를 생성할 수도 있다. 팩토리 함수는 생성자 함수/클래스 이외에 객체를 생성하는 함수를 모두 팩토리 함수라고 한다.
캡슐화(Encapsulation)
캡슐화는 객체 내의 데이터에 접근할 수 없도록 하는 것을 말한다.
객체 내의 데이터 중, 객체 내에서만 동작하는 데이터는 내부에서만 동작하고 외부에서 접근할 수 있는 데이터는 그렇게 동작하도록 하는 것이다. 이런 캡슐화로 인해서 객체의 안정성을 높이는 데 도움이 된다.
변수를 외부로 부터 숨기는 것을 은닉이라고 하는데, 자바스크립트에서는 보통 클로저를 통해서 구현되는 경우가 많다.
보통의 객체 지향 프로그래밍 언어에서는 private 메소드를 지원한다.
자바스크립트에서는, ES2019에서 #을 통해서 private를 할 수 있게 되었다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes/Private_class_fields
상속(Inheritance)
상속은 보통 부모님이 자식에게 재산을 물려주는 것이다.
여기서는 어떤 생성자 함수가 하위 생성자 함수에게 자신들의 특성을 그대로 물려주는 것을 의미한다.
상속은 프로토타입의 작동 위임을 통해 일정부분 구현할 수 있다.
뒤에 설명할 추상화와 다형성도 프로토타입을 이용한 구현의 확장이다.
추상화(Abstraction)
추상이라는 것은, 어떤 복잡한 부분이나 자질구레한 부분을 제외하고 핵심적인 요소만 남기는 것을 말한다.
예를 들어, 어떤 생성자 함수 Dog와 Cat, Rabbit이 있다고 가정해보자.
각각의 생성자 함수를 정의해서 사용할 수도 있겠지만, 이들에게 나타나는 공통점을 묶을 수도 있다.
예를 들면 개와 고양이, 토끼 모두 털이 있다는 특징이 있고, 뛰어다니는 동작을 할 수가 있다.
그래서 공통점을 묶어 하나의 공통적인 Animal 생성자 함수를 만들 수 있다.
그리고 Dog와 Cat, Rabbit의 prototype의 __proto__를, Animal prototype로 연결해 하위 생성자 클래스로서 동작할 수가 있는 것이다.
const Animal = function () {
this.coat = '복슬복슬';
};
Animal.prototype.run = function () {
console.log('폴짝폴짝');
};
const Dog = function () {
Animal.call(this);
this.speak = "멍멍";
};
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const Cat = function () {
Animal.call(this);
this.speak = "야옹";
};
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
const minggu = new Dog();
const coco = new Cat();
console.log(minggu.coat); // "복슬복슬"
console.log(coco.coat); // "복슬복슬"
minggu.run(); // "폴짝폴짝"
coco.run(); // "폴짝폴짝"
다형성(Polymophism)
다형성은 같은 메소드를 각 클래스에 맞춰서 다르게 사용하는 것을 의미한다.
상속을 통해 같은 메소드를 물려받게 되었지만, 클래스마다 새로운 메소드를 작성하여 이를 덮어쓰기 하는 것이다.
그렇게 해서 각 객체 마다 같은 메소드를 실행하여도, 각자 다른 방식으로 동작하게 된다.
자바스크립트에서는 prototype chain에 의해서, 해당 생성자 함수가 가지고 있는 prototype을 먼저 참고한다.
자식 클래스에서 별도의 프로토 타입 메소드를 등록했을 때, 이를 따로 신경쓰지 않아도 다형성을 구현할 수 있게 된다.
참고 -
https://im-developer.tistory.com/136