[TIL] 클래스와 추상화

Narastro·2021년 7월 27일
0

TIL

목록 보기
6/16
post-thumbnail

🧀 클래스와 오브젝트, 그리고 인스턴스

클래스(Class)

  • 객체를 만들어 내기 위한 틀
  • 시작 문자를 대문자로 하는 게 암묵적 룰.

오브젝트(Object)

  • 구현 대상 (클래스의 인스턴스)

인스턴스(instance)

  • 구현된 구체적 실체
  • 메모리에 할당됨.

🚀 상속과 다형성

상속

  • 우리는 모두 사람이라는 클래스에서 상속받았다?

어떤 클래스에서 더 확장된 클래스를 만들 수 있다. 쉽게 말해 상위 클래스의 모든 상태(status)와 행동(method)을 그대로 물려 받는 것이다. 그리고 이를 그대로 사용할 수도 커스터마이징 할 수도 있다.

다형성

한 행동을 여러 방법으로 구현하고 상황에 따라 적당한 구현을 선택해서 쓰도록 하는 기능을 제공하는 것을 말한다.

  • 어떤 클래스에서 서로 다른 매개변수를 써서 한 개의 메서드를 두 가지 버전으로 정의
  • 부모와 자식 클래스에서 같은 메서드를 다르게 정의하여 오버라이딩하도록 정의.

💻 Class와 Prototype

Class

  • new 키워드를 통해 인스턴스 생성

Prototype

  • 다른 객체로부터 직접 인스턴스가 상속

📗 this와 super의 차이점

this 키워드는 해당 클래스의 생성자를 직접 가르키는 반면 super.method()를 쓰거나 생성자에서 super()를 하여 상위 클래스의 메서드나 생성자를 가져올 수 있다.

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 {
  constructor(width, height, color){
     super(width,height,color);
  }
  draw() {
    super.draw(); // 부모 함수 호출 super.method()
    console.log('🔺');
  }

💬 SOLID 원칙

  • 객체 지향 5대 원칙
    SRP(단일 책임 원칙), OCP(개방-폐쇄 원칙), LSP(리스코프 치환 원칙), DIP(의존 역전 원칙), ISP(인터페이스 분리 원칙)

  • 그들의 앞자를 딴 것

  • 프로그래머의 유지 보수와 확장을 돕기 위해.

1. Single Responsibility Principle (단일 책임 원칙)

  • 클래스는 단 한 개의 책임. (클래스를 변경하는 이유는 단 한 개여야 함)
  • 여러 책임을 갖으면 책임마다 변경될 우려
  • 여기서 책임이란, '기능' 정도의 의미로 해석하면 된다.

"좋은 설계는 응집도가 높고 결합도가 낮은 프로그램을 설계하는 것을 말한다. 만약 한 클래스가 수행할 수 있는 기능이 많아지면 내부의 함수끼리 강한 결합을 발생할 가능성이 높아진다. 이는 유지보수 비용이 증가하게 되므로 이를 분리시킬 필요가 있다."

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

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

OCP에 만족하는 설계를 할 때 변경되는 것이 무엇인지에 초점을 맞춘다. 자주 변경되는 내용은 수정하기 쉽게 설계 하고, 변경되지 않아야 하는 것은 수정되는 내용에 영향을 받지 않게 하는 것이 포인트다.

만약 음악 형식을 재생하는 플레이어 클래스를 정의하고 그 내부에서 새로운 형식이 정해질 때마다 메서드를 수정하는 것보다, 새로운 형식을 클래스로 지정하고 플레이어 클래스를 상속받아 플레이 메서드를 재정의하는 것이 좋다.

결과적으로 우리는 SoundPlayer 클래스의 변경 없이 재생되는 파일을 바꿀 수 있으므로 OCP를 만족한다. 앞서 말했듯이 OCP를 만족한 설계는 변경에 유연하므로 유지보수 비용을 줄여주고 코드의 가독성 또한 높아지는 효과를 얻을 수 있다.

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

  • 자식 클래스는 부모클래스에서 가능한 행위를 수행할 수 있어야 한다.
  • 서브타입은 언제나 상위 타입으로 교체 가능해야 함.
  • 상속에 관한 지침
  • 예시) 오리와 오리장난감 - 배터리 관점에서는 LSP 위반이나 클라이언트의 사용방식(구경거리로 본다면)에 따라 아닐 수도 있다.

리스코프 치환 원칙은 MIT 컴퓨터 사이언스 교수인 리스코프가 제안한 설계 원칙이다. 부모 클래스와 자식 클래스 사이의 행위에는 일관성이 있어야 한다는 원칙이며, 이는 객체 지향 프로그래밍에서 부모 클래스의 인스턴스 대신 자식 클래스의 인스터스를 사용해도 문제가 없어야 한다는 것을 의미한다.

상속 관계에서는 일반화 관계(IS-A)가 성립해야 한다. 일반화 관계에 있다는 것은 일관성이 있다는 것이다. 따라서 리스코프 치환 원칙은 일반화 관계에 대해 묻는 것이라 할 수 있다.

만약 도형에 대해 상속받았을 때, 원은 각을 가지고 있다와 같은 어색한 문장이 생긴다. 이러한 경우 일반화 관계가 성립하도록 수정해줘야 한다.

4. Dependency Inversion Principle (의존 역전 원칙)

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

여기서 말하는 변화하기 쉬운것이란 구체적인 것을 말하고, 변화하기 어려운 것이란 추상적인 것을 말한다. 객체지향적인 관점에서 보자면 변화하기 쉬운것이란 구체화 된 클래스를 의미하고, 변화하기 어려운 것은 추상클래스나 인터페이스를 의미한다. 따라서 DIP를 만족한다는 것은 의존관계를 맺을 때, 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺는다는 것을 의미한다.

DIP를 만족하면 '의존성 주입' 이라는 기술로 변화에 유연한 설계를 할 수 있다.

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

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

이는 다시 말해서, 자신이 사용하지 않는 기능(인터페이스)에는 영향을 받지 말아야 한다는 의미이다.

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

출처: https://dev-momo.tistory.com/entry/SOLID-원칙 [Programming Note]

🎈 자바스크립트 성능을 높이는 코드 스타일

참고해보자!

🥨 프로퍼티(Property) & 메소드(Method)

프로퍼티

ECMA5에서 프로퍼티는 객체의 일부로 이름과 값 사이 연결을 의미 라고 정의 한다. 객체의 속성을 나타내는 접근 가능한 이름과 활용 가능한 값을 가지는 특별한 형태이다.

메서드

메소드는 객체가 가지고 있는 동작이다. 자바스크립트에서의 메소드는 각각 개별 객체로 존재 한다. 그 사용법은 동일하지만 객체에 속한 메타 데이터를 사용하는 것이 아닌 그 객체로 부터 파생되어 확장된 새로운 객체를 사용하는 것이다.

  • 참조값을 저장함

🍡 자바스크립트에서의 캡슐화

  • _프로퍼티로 private
function MyClass() {

    //public 프로퍼티
    this.프로퍼티이름 =;

    //private/protected 프로퍼티
    this._프로퍼티이름 =;
}

// public 메서드
MyClass.prototype.메서드이름 = function() {

}
// private/protected 메서드
MyClass.prototype._메서드이름 = function() {

}
  • _(underBar) 를 붙이는 것은 외부에서 언더바를 붙힌 프로퍼티나 메서드에 접근하여 사용하지 말라는 암묵적인 약속

  • 클래스(생성자함수)명의 시작문자를 대문자로 사용하는 것과 마찬가지.

  • 캡슐회는 만일의 상황(타인이 외부에서 조작)을 대비해서 외부에서 특정 속성이나 메서드를 시용자가 사용할 수 없도록 숨겨놓은 것.

출처: https://webclub.tistory.com/156 [Web Club]

😄 느낀점

사실 오늘은 재밌었던만큼 늦게 마무리하였다. 내가 아는 룰과 최대한 맞추기 위해 이리저리 에러를 해결했고, 클래스의 사용도 조금 익숙해졌다. 코드를 짜기 전 설계의 중요성을 느낀 하루였다. 오늘도 힘들지만 뿌듯하다!

profile
Earn this, Earn it.

0개의 댓글