프로토타입 기반 프로그래밍은 객체지향 프로그래밍의 한 형태의 갈래로 클래스가 없고, 클래스 기반 언어에서 상속을 사용하는 것과는 다르게, 객체를 원형으로(프로토타입)으로 하여 복제의 과정을 통하여 객체의 동작 방식을 다시 사용할 수 있다. 프로토타입기반 프로그래밍은 클래스리스(class-less), 프로토타입 지향(prototype-oriented) 혹은 인스턴스 기반(instance-based)프로그래밍이라고도 한다.
프로토타입 기반 언어의 가장 원조격인 프로그래밍 언어인 셀프는 데이비드 엉거와 랜덜 스미스가 개발했다. 클래스리스 프로그래밍은 최근에 와서 많이 유명해졌는데, 자바스크립트와 모픽 프레임워크를 사용하는 스퀵에 적용되었고, 그 외에 세실, 뉴튼스크립트, 아이오, 무, 리볼, 케보 등에 적용되었다.
클래스 기반과의 비교
클래스기반 언어에서 객체는 일반적으로 두 가지 형태가 있다. '클래스'는 객체의 기본적인 만듦새와 기능을 정의하고, '인스턴스'는 "사용할 수 있는" 객체로 특정 클래스의 양식을 기반으로 한다. 클래스기반 언어에서 '클래스'는 동작 방식인 메소드의 모임으로 동작하고, 모든 인스턴스의 구조는 동일하고 인스턴스는 객체의 자료를 가지고 있다. 한쪽에는 구조와 동작 방식, 다른 한쪽에는 상태로 구분된다. 프로토타입 기반 프로그래밍을 지지하는 사람들은 클래스기반 언어에서는 개발자가 클래스들 사이의 분류와 관계에 먼저 초점을 맞추기 쉽다고 한다. 이와는 달리, 프로토타입기반 프로그래밍은 프로그래머가 여러가지 표본의 동작 방식에 초점을 맞추고, 이 객체들을 나중에 클래스와 비슷한 방식의 "객체의 원형"으로 분류하는 것은 나중에 걱정해도 된다. 많은 프로토타입기반 체계가 실행시간에 프로토타입을 대체하기 쉬우나, 클래스기반 객체지향 체계에서는 최초의 동적 객체지향 체계인 스몰토크와 같이 프로그램의 실행 중에 클래스를 바꿀 수 있는 것은 몇 가지 되지 않는다. 프로토타입 기반 프로그래밍은, 학습의 과정의 주요한 특징으로 프로토타입이나 이그젬플러를 강조하는, 인지 심리학과 같은 특정 학문과 관련되어 있는 경우가 많다. 프로토타입 기반 체계의 대부분은 인터프리터이고 동적 타입 프로그래밍 언어이다. 하지만 프로토타입기반의 정적 타입의 체계가 기술적으로 가능하다. 오메가는 그런 체계의 한 예이다.
객체 생성
클래스기반 언어에서, 클래스의 생성자를 통하거나 필요하다면 생성자와 생성자의 매개변수를 통하여 인스턴스를 새로 만든다. 결과로 만들어지 인스턴스는 선택된 클래스의 설계와 행동을 따르게 된다. 프로토타입기반 체계에서, 새 객체를 만드는 두 가지 방법이 있다. 하나는 원래 있던 객체를 '복제(cloning)'하는 방법이고, 다른 하나는 '무에서 객체를 생성하는 방법이다. 대부분 다양한 복제 방식을 제공하기 때문에 무에서 객체를 생성하는 것은 흔하지 않다. 무에서 객체를 생성할 수 있는 체계는 이미 있던 프로토타입을 복제하지 않고 아무것도 없는 상태에서 새로운 객체를 생성할 수 있게 해 준다. 이런 체계는 새 객체의 특성과 행동을 이미 있던 객체를 참조하지 않고도 지정할 수 있다. 많은 프로토타입기반 언어에서 기본 객체 프로토타입인 Object객체와 네임스페이스 충돌이 일어나지 않는다는 것이다. 모질라 자바스크립트는 객체의 __proto__프로퍼티를 null로 지정하면 이것이 가능하도록 구현되어 있다. '복제'는 원래 있던 객체의 프로토타입의 행동을 복제하여 새 객체를 생성하는 과정을 거친다. 새 객체는 원본의 모든 특성을 가진다. 이 상태에서 새 객체를 수정할 수 있다. 어떤 체계에서 복제된 자식 객체는 명시적으로 프로토타입과 '위임(delegation)'이나 '닮음(resemblance)'으로 연관되어 있다. 그래서 프로토타입을 변경하면 복제품에 영향을 끼친다. 포스와 케보 같은 다른 체계에서는 프로토타입을 번식시키는 이런 방식을 따르지 않고, 대신에 프로토타입을 수정하더라도 복제품에는 영향을 끼치지 않는 연쇄된 형태를 사용하여 원본 객체를 수정하더라도 그 자손으로 자동 번식되지 않는다.
위임
실행시간에 '위임'하는 프로토타입기반의 언어들은 올바른 메서드로 동적 디스패치를 할 수 있거나, 맞는 자료조각에 이를때 까지 객체에서 프로토타입으로 간단히 위임포인터를 연속적으로 따라가서 찾을 수 있다. 객체들사이에서 동작을 공유하는 것을 확립하기 위해 필요한 것들은 위임 포인터 뿐이다. 클래스기반 객체 지향 언어에서 클래스와 인스턴스의 관계와 달리 프로토타입과 파생된 객체는 이 연결을 통하여 프로토타입과 자식 객체가 메모리나 구조적인 유사성을 가질 필요가 없다. 마찬가지로, 자식 객체는 클래스 기반의 연관된 클래스의 구조를 재배치하지 않고 계속해서 수정할 수 있다. 또 중요한 점은, 자료뿐만 아니라 메서드도 추가되거나 변경될 수 있다는 것이다. 이런 이유로 대부분의 프로토타입기반 언어들은 자료와 메서드 두가지 모두 슬롯으로 관리한다.
연쇄
순수 프로토타입은 '연쇄적' 프로토타입이라고도 하는데 케보가 그 예이다. 원본 프로토타입에서 복제된 객체로 포인터는 보이지 않는다. 프로토타입 객체는 정확히 복사되지만, 다른 이름이나 참조값을 갖는다. 이 과정은 생물학적인 미토시스와 비교할 수 있다. 메서드와 속성은 대응되는 것으로 중복된다. 이렇게 접근하면 객체 작성자가 한 부모 객체의 자식 객체들간에 부수효과를 신경쓰지 않고 복제할 수 있다는 이점이 있다. 또 다른 이점은, 디스패치 중 메서드 미리보기의 계산비용이 위임에 비해서 급격히 줄어든다는 것이다. 위임을 하면 적합한 메서드나 슬롯을 찾는 것을 실패한다면 전체 위임사슬에서 찾아봐야 하기 때문이다. 연쇄 접근 방식의 단점은 시스템을 통해 바뀌는 것을 번식시키는 데에 조직적으로 어렵다는 것이다. 프로토타입에 변화가 생기면 이것은 복제품에 즉시 혹은 자동적으로 적용되지 않는다. 그러나 케보는 위임방식에서 주로 쓰는 분류상의 원형을 사용하지 않고, 추가적인 기본형을 제공하여 '가족닮음(family resemblance)라고 하는 유사한 객체들을 모아서 변화를 적용한다. 다른 단점은 이 형태를 세련되게 구현하지 못하면 원형과 복제품이 같은 부분에서 복제품들이 위임 형태에 비해서 메모리가 더 많이 낭비된다는 것이다. 그러나 케보에서 실제로 하고 있는 접근 방식처럼 공유하도록 구현하고 자료는 배후에 두는 방식으로 프로그래밍에 대한 연쇄적 행동이 가능하다.
'필사적 필사' 카테고리의 다른 글
자바스크립트 동시성 모델과 이벤트 루프 (0) | 2020.03.18 |
---|---|
자바스크립트 비동기 처리 과정과 Rxjs Scheduler (0) | 2020.03.17 |
JIT 컴파일 (0) | 2020.01.21 |
NMS 알고리즘 (0) | 2020.01.09 |
.net framework란 무엇일까? (0) | 2019.12.31 |