JavaScript

201028 수 TIL Object Oriented Programming(객체지향 프로그래밍) - JavaScript

파란배개 2020. 10. 28. 11:22

1. 컴퓨터 프로그래밍의 세 가지 가족

  • 기계어
  • 어셈블리어
  • 고급 언어

 

 

1-1. 기계어

  • 0과 1로 조합된다
  • 컴퓨터의 네이티브 언어이다
  • 프로그램 하기 어렵다(1이나 0을 하나만 잘 못 써도 프로그램이 작동하지 않는다)

 

1-2. 어셈블리어

  • 특정 어셈블리어는 해당하는 어셈블리어로 만들어진 cpu에만 돌아가며 적은 명령어로 이루어진다
  • 기계어에 비해 접근하기 쉬운 프로그래밍 언어이다
  • 컴퓨터가 처리하기 위해서는 기계어로 번역되어야 한다

 

1-3. 고급언어

  • 영어와 비슷하게 만들어진다
  • Interpreter가 컴파일을 하지 않아도 한 줄씩 읽어들여 완성되지 않아도 바로 볼 수 있도록 코드를 처리해준다
  • 고급언어는 절차 지향 언어(Procedural languages)와 객체 지향 언어(Object-Oriented languages) 두 종류다

 

 


*프로그래밍 언어*
  • 어셈블리어를 이용해 함수들을 만들어 사용하는 고급 언어가 우리가 일반적으로 쓰는 프로그래밍 언어이다
  • 컴파일(번역) 과정을 거쳐 어셈블리어로 바뀌고 또 기계어로 바뀐다(자바스크립트는 컴파일하지 않으므로 제외한다)
  • 고급 언어에 가까울 수록 여러가지 환경에서 쓸 수 있고(Flexiility) 유연하게 쓸 수 있으며(Portability), 구현하기 쉽다(Ease of Implementation)
  • 기계어에 가까울 수록 처리 속도가 빠르고(Speed of Execution) 코드가 압축(Code Density)되고 특정 머신에 종속(Machine Specific)된다

 

1-3-1. 절차 지향 언어 (Procedural Languages)

  • -초기의 고급 언어 대부분이 절차 지향 언어였다
  • -프로그램 사이의 함수와 변수가 어떤 절차로 이어지는가가 핵심이다
  • -C, COBOL, Perl, HTML, Fortran, LISP, VBScript 등이 해당한다

 

1-3-2. 객체 지향 언어(Object-Oriented Languages)

  • -클래스라는 데이터 모델의 청사진을 사용한다
  • -Java, C++, C#, Python, PHP, JavaScript, Ruby, Perl, Object Pascal, Object-C, Dart, Swift, Scala, Common Lisp 등

2. 객체 지향 프로그래밍(Object Oriented Programming, OOP)

  • 객체지향 프로그램이란, "사람이 세계를 보고 이해하는 방법을 흉내낸 방법론"이므로 현실 세계의 모델을 코드로 옮기는데 유리하다
  • 객체 지향 프로그램에서는 모든 것이 Object로 되어 있다
  • 객체지향 프로그래밍은 재사용성이 높다 ex)자동차라는 class가 있다면 자동차의 공통된 기본 기능(운전이 가능, 기름을 주유한다)에 다른 설정값을 이용해(차의 색깔, 이름, 크기 등) objects를 만들어낸다

 

2-1. 객체 지향 프로그래밍의 네 가지 특징

  • Encapsulation(캡슐화)

= (운전기능, 주유기능, 색상, 가격, 속도, 크기 같은)  속성들을 Car 라는 class혹은 object에 모아놓는다

캡슐화의 장점 = Reduce complexity + increase resusability

let baseSalary = 30_000;
let overtime = 10;
let rate = 20;

function getWage(baseSalary, overtime, rate) {
	return baseSalary + (overtime *rate);
}
//이걸 OOP에서는

let employee = {
    baseSalary: 30_000,
    overtime: 10,
    rate: 20,
    getWage: function() {
    	return this.baseSalary + (this.overtime * this.rate);
    }
};
employee.getWage();
//이런 식으로 객체에 모아놓는다는 뜻

 

  • Inheritance(상속)

= 상위 객체의 특징을 하위 객체에 넘겨주며 자식 객체는 부모 객체의 기능을 베이스로 새로운 기능을 추가한다

상속의 장점 = Eliminate redundant code

  • Abstraction(추상화)

=구조는 복잡하지만 실제 사용할 때는 간단하게 사용 가능(전화기의 원리를 몰라도 전화기 사용은 간단하듯이)

추상화의 장점 = Reduce complexity + isolate impact of changes

  • Polymorphism(다형성)

=다형성의 두 가지 특징으로 부모 클래스의 메소드를 하위 클래스에서 수정해서 다른 기능을 하게 만드는 오버라이딩과, 같은 이름의 메소드이지만 인자의 개수나 자료형에 따라서 다른 기능을 하게 만드는 오버로딩을 특징으로 가진다

다형성의 장점 = Refactor ugly switch/case statements

-----------------------------------------------

3. Instantiation Patterns


Instantiation란?

더보기
  • 인스턴스(복제품)를 만드는 과정이다

Class란?

  • 더보기
    하나의 정형화된 모델을 만들고 그 모델을 기반으로 인스턴스를 만들기 위해 사용한다.
  • 더보기
    ex) Car라는 객체는 항상 position이라는 속성(property)와, move라는 method를 가지고 있고 Car1, Car2, Car3... 등의 매우 많은 Car들을 사용하는 프로그램을 작성한다고 했을 때, 각각의 Car들에게 하나하나 변수를 선언하는 것은 비효율적이다. 이 때 OOP의 class를 이용하면 Car라는 하나의 모델을 만들어 두고 비슷한 객체들을 함수를 이용해 찍어내면 된다.

3-1. class가 나오기 전 JavaScript의 4 가지 Class 선언 방식

3-1-1. Functional Instantiation

= 함수를 이용해서 찍어내는 방식이다

let Car = function(position) {
  let someInstance = {}; //함수의 결과로 출력될(찍어져 나올) 객체를 선언
  someInstance.position = position;
  someInstance.move = function() {
    this.position += 1;//여기서 this는 someInstance
  }
  return someInstance;
}

let car1 = Car(5);//초기위치가 5인 car1 인스턴스 생성
let car2 = Car(0);
car1.move()
console.log(car1) // {position : 6, move : function(){this.position+=1}}

3-1-2. Functional Shared 

= Functional Instantiation 방식은 인스턴스를 생성할 때마다 모든 메소드를 someInstance에게 할당해서 각각의 인스턴스들이 메소드의 수 만큼 메모리를 더 차지하는 문제가 있다

이를 해결하기 위해 someMethods라는 객체에 있는 메모리 주소만을 참조하는 Functional Shared이라는 더 효율이 좋은 방식이 생겼다

let extend = function(to, them) {//someInstance와 someMethods를 합치는 함수를 만들어 Car 함수 내부에서 합친다
  for(let key in from) {
    to[key] = from[key];
  }
}

let someMethods = {};//method를 담을 객체를 따로 생성한다
someMethods.move = function() {
  this.position += 1;
}

let Car = function(position) {//Car 함수를 선언한다
  let someInstance = {
    position: position,
  }//Functional instanciation과 다르게 someInstance 안에 position을 바로 넣어준다
  extend(someInstance, someMethods);
  return someInstance;
}

let car1 = Car(5);
let car2 = Car(10);

 

3-1-3. Prototypal Instantiation

= 특정 객체를 프로토타입으로 하는 객체를 생성해주는 Object.create를 사용하는 방식이다

let someMethods = {};
someMethods.move = function() {
  this.position += 1;
}

let Car = function(position) {
  let someInstance = Object.create(someMethods);//이 부분이 Function shared와 다르다
  someInstance.position = position;
  return someInstance;
}

let car1 = Car(5);
let car2 = Car(10);

 

3-1-4. Pseudoclassical Instantiation

= ES6 class 키워드를 이용한 방법과 내부적으로 동일한 방식이며 가장 많이 사용된다

class 키워드를 사용하지 않는 방법 중 간장 간단하지만 인스턴스를 만들 때는 new operator를 붙여야 한다.

let Car = function(position) {
  this.position = position;
}

Car.prototype.move = function() {//Prototypal Instantiation과는 다르게 처음부터 메소드를 프로토타입으로 만든다.
  this.position += 1;
}

let car1 = new Car(5);
let car2 = new Car(10);
//Pseudoclassical Instantiation는 간단하지만 인스턴스를 만들 때는 new operator를 붙여야 한다.