[TIL] 객체 지향 프로그래밍

swing·2021년 1월 27일
2

[TIL]

목록 보기
3/10

## 클래스와 오브젝트, 인스턴스 / 상속과 다형성

  • class : 템플릿, 혹은 청사진으로 불리우며 es6에서 추가된 문법이다.
    object를 만들던 prototype에 class 문법을 추가하였다.
    비유하자면 클래스는 붕어빵틀이고 오브젝트는 실제 만들어진 붕어빵이다.
    클래스에는 직접적인 데이터가 들어가있지 않지만, 오브젝트를 만들 수 있는 틀을 제공하는 셈이다.
    그리고 오브젝트 선언을 통해 어떠한 붕어빵을 만들것인지 결정할 수 있는 것이다.
    가령 데이터를 팥으로 넣는다 하면, 그것은 붕어빵틀이라는 클래스에 맞춰 팥붕어빵으로 탄생하는 것이다.

  • 인스턴스의 예를 들어보자.
const obj = new Object;

라는 코드가 있다면 변수에 할당된 오브젝트가 바로 인스턴스이다.
이 말은 new Object가 obj에 할당되었고 , 동시에 obj변수의 instance가 된다.
인스턴스를 생성하는 이유는 간단하다. 각 인스턴스마다 다른 값을 용이하게 유지보수하기 위함이다.
가령 인스턴스를 생성하지 않았다고 하면, 클래스 고유의 값을 매번 변경해 주어야 한다. 다형성이 현저히 낮아진다.
객체지향 프로그래밍 OOP란 즉, 인스턴스를 이용한 다형성을 부여하는 획기적인 일이다. 그로 인해 유지보수가 월등히 쉬워진 것이다.


this(또는 self)와 super 키워드 차이점에 대해 정리한다.

  • this 키워드는 해당 클래스 생성자를 직접 가르킨다.
class Shape {
  constructor(width, height, color) {
    this.width = width;
    this.height = height;
    this.color = color;
  }

  draw() {
    console.log(`drawing ${this.color} color!`);
  }

  getArea() {
    return this.width * this.height;
  }
}

class Triangle extends Shape {
  draw() {
    super.draw(); // 부모 함수 호출 super.method()
    console.log('🔺');
  }

위의 코드에서 Triangle 이란 클래스에 Shape class를 확장시켰다.
이렇게 함으로써, 공통적으로 가진 특성을 확장시켜 다형성을 늘린 것이다.
여기서 shape class의 this 키워드를 보면, 해당 클래스에 직접적인 property를 저장한다.
이제 Shape class를 extends한 Triangle class를 보자.
shape에도 있는 draw method를 다시 정의한다. 이렇게 하면 해당 메소드를 현 클래스 입맛에 맞게 바꿀 수 있다.
입맛에 맞게 바꿈과 동시에 기존 메소드를 배껴오고 싶을 수도 있다.
그럴 때는 super.method()를 사용하여 상속하는 클래스의 메소드를 그대로 가져올 수 있다.


객체 인스턴스 비교 방법에 대해 정리한다.

  • Class는 하나의 메모리를 할당한다. 그 메모리에서 object property에 맞게 값이 변경된다.
class Rectangle extends Shape {} // Shape을 상속하는 Rectangle
class Triangle extends Shape {}

const rectangle = new Rectangle; // new object 생성
const triangle = new Triangle;

console.log(rectangle instanceof Rectangle); // 왼쪽의 객체가 우측 클래스의 instance인지 확인 // true
console.log(triangle instanceof Rectangle); // false
console.log(triangle instanceof Triangle); // true
console.log(triangle instanceof Shape); // true
console.log(triangle instanceof Object); // true , JS의 모든 object는 class Object를 상속한다. , 그말은 즉슨 Object의 메소드를 쓸 수 있다.

SOLID 원칙

객체 지향 5대 원칙이라고도 불리운다.
SOLID를 풀어 쓰면,
SRP(단일 책임 원칙)
OCP(개방-폐쇄 원칙)
LSP(리스코프 치환 원칙)
ISP(인터페이스 분리 원칙)
DIP(의존 역전 원칙)
의 앞글자를 따서 SOLID 원칙이라 통칭한다.


Single Responsiblity Principle (단일 책임 원칙)

  • 소프트웨어의 설계 부품(클래스,함수 등)은 단 하나의 책임만을 가져야 한다.

여기서 책임이란, 기능 정도의 의미로 해석한다.
한 클래스,함수에서 수행하는 기능이 많아질수록 유지보수에 불리하다.
SRP가 안지켜진 사례에는 아래의 경우들이 있다.

  • 하나의 속성이 여러 의미를 갖는 경우
  • 어떤 곳에서는 쓰고, 어떤 곳에서는 쓰지 않는 속성이 있는 경우

Open-Closed Principle (개방-패쇄 원칙)

  • 기존의 코드를 변경하지 않고(Closed) 기능을 수정하거나 추가할 수 있도록(Open) 설계해야 한다.

기능 확장에 개방적이고, 기능 수정에 패쇄적이어야 한다.
이는 연관되는 기능을 묶는 추상화를 통해 이루어진다.
상점을 예로 들자면, 상점 직원이 아무리 바뀌어도 손님은 상품을 구매하는데 지장이 없다.
이는 직원은 판매인터페이스를 구현하고, 손님은 판매인터페이스와만 소통하기 때문이다.


Liskov Substitution Principle (리스코프 치환 원칙)

  • 자식 클래스는 부모클래스에서 가능한 행위를 수행할 수 있어야 한다.

부모 클래스와 자식 클래스 사이의 행위에는 일관성이 있어야 한다는 원칙이며, 이는 객체 지향 프로그래밍에서 부모 클래스의 인스턴스 대신 자식 클래스의 인스터스를 사용해도 문제가 없어야 한다는 것을 의미한다.

이해를 돕기위해 도형을 예시를 들어보자. 도형 클래스와 사각형 클래스가 있고, 사각형 클래스는 도형 클래스의 상속을 받는다고 가정하자.

(1) 도형은 둘레를 가지고 있다.

(2) 도형은 넓이를 가지고 있다.

(3) 도형은 각을 가지고 있다.

일반화 관계(일관성인지 확인하는 방법은 단어를 교체해 보면 알 수 있다. (1) ~ (3)의 도형이란 단어 대신 사각형을 넣어보자.

(1) 사각형은 둘레를 가지고 있다.

(2) 사각형은 넓이를 가지고 있다.

(3) 사각형은 각을 가지고 있다.

(1) ~ (3) 모두 딱히 이상한 부분이 보이지 않는다. 따라서 도형과 사각형 사이에는 일관성이 있다고 할 수 있다.

여기서 원(Circle) 이라는 도형에 대해 생각해보자. 원 클래스 역시 도형 클래스의 상속을 받는다고 가정하자. 앞에서 언급한 (1) ~ (3)의 도형 단어 대신 원을 대입해보자.

(1) 원은 둘레를 가지고 있다.

(2) 원은 넓이를 가지고 있다.

(3) 원은 각을 가지고 있다.

문장을 읽어보면 (3)번 문장이 어색하다는 것을 알 수 있다. 따라서 도형 클래스는 LSP을 만족하지 않은 설계라 할 수 있다. 따라서 (3)문장에 대해서는 일반화 관계가 성립하도록 수정되어야 한다.


Interface Segregation Principle (인터페이스 분리 원칙)

  • 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다. 하나의 일반적인 인터페이스보다는, 여러 개의 구체적인 인터페이스가 낫다.

한가지 예를 들어보자. 우리는 스마트폰으로 전화, 웹서핑, 사진 촬영 등 다양한 기능을 사용할 수 있다.
그런데 전화를 할 때에는 웹서핑, 사진촬영 등 다른 기능은 사용하지 않는다.
따라서 전화기능과 웹서핑 기능 사진 촬영 기능은 각각 독립된 인터페이스로 구현하여, 서로에게 영향을 받지 않도록 설계해야 한다.
이렇게 설계된 소프트웨어는 인터페이스 분리 원칙을 통해 시스템의 내부 의존성을 약화시켜 리팩토링, 수정, 재배포를 쉽게 할 수 있다.


Dependency Inversion Principle (의존 역전 원칙)

  • 의존 관계를 맺을 때, 변화하기 쉬운것 보단 변화하기 어려운 것에 의존해야 한다는 원칙이다.

변화하기 쉬운 것은, 구체화 된 클래스를 의미하고, 어려운 것은 추상화된 클래스로 이해한다.

profile
if(기록📝) 성장🌱

0개의 댓글