JavaScript와 객체지향 프로그래밍...

Kim-DaHam·2023년 3월 15일
0

JavaScript

목록 보기
10/18
post-thumbnail

🔥 학습목표

  • 객체 지향 프로그래밍에 대해 설명할 수 있다.
  • 객체 지향 프로그래밍의 근본 조건에 대해 설명할 수 있다.
  • 자바스크립트 DeepDive 25장을 학습한다.
  • '한 번 읽으면 두 번 깨닫는 객체지향 프로그래밍'를 복습한다.



('한 번 읽으면 두 번 깨닫는 객체지향 프로그래밍' 참고.)

🟩 객체 지향 프로그래밍

좋은 소프트웨어를 만드는 원칙을 간결하게 한 문장, 두 가지 권고사항으로 정리할 수 있다.

"관계의 의존성은 낮게, 기능의 집중도는 높게"

=> 높은 응집도(기능의 집중도)와 낮은 결합도(관계의 의존성)

🟣 객체 지향의 정의

OOP (Object Oriented Programming)

객체 지향 프로그래밍은 프로그램 설계 철학 중 하나다. 모든 것이 "객체"로 그룹화 된다.

⬜ 객체지향의 기본 개념

"객체지향은 낮은 관계의 의존성과 높은 기능의 집중도를 지향하여, 소프트웨어의 유연함을 극대화하는 개발 기법이다."

객체 지향 프로그래밍은 (대표적으로) 네 가지 특성을 가지고 있다.

  • 캡슐화
  • 상속
  • 추상화
  • 다형성

아래에서 자세하게 정리하도록 한다.


⬜ 객체지향의 목표

"점(객체 하나)보다 선(객체 간의 협력 관계)로 접근한다."

객체지향적 개발이란, 곧 "유연한 코드"를 작성하는 것이다.

유연한 소프트웨어란, 코드 품질의 향상이다.

  • 코드 중복이 거의 없고
  • 코드 속성과 메소드의 캡슐화가 잘 되어있고
  • 코드 배치의 일관성이 잘 지켜지고
  • 가독성이 좋고, 코드 의존성이 낮아지고
  • 그로인해 사이드 이펙트가 줄어들고
  • 재사용이 쉽고
  • 코드 수정, 추가, 디버그가 쉬우며
  • 유지보수와 고도화 프로젝트를 하기에 좋아진다.



🟩 객체 지향의 근본 조건 4가지

자바스크립트에서, 객체지향의 장점이자 사상인 "낮은 관계의 의존성과 높은 기능의 집중도"를 지키기 위한 필수 조건 4가지에 대해 정리한다.

(본래 책에서는 Java 를 기준으로 7가지를 설명하는데, 오버로딩/오버라이딩 등 JavaScript에서는 굳이 따질 필요 없는 것들을 제외한 4가지만 정리하였다.)

🟣 캡슐화(Encapsulation)

비슷한 기능과 역할을 하는 메서드, 속성을 어떤 틀 안에 숨기고 보호한다.

└▶ 데이터(속성)와 기능(메서드)을 따로 정의하지 않고, 하나의 객체에 담아 묶는 것이다. 데이터와 기능들이 느슨하게 결합 된다.

즉,

  • 데이터와 기능을 하나의 단위로 묶는다.
  • 구현은 은닉(hiding)하고, 동작은 노출한다.
  • 언제든 구현을 수정할 수 있다. -> 느슨한 결합(Loose Coupling)에 유리하다.

느슨한 결합?
└▷ 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아니라, 코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것.


모든 기능을 절차적으로 이곳저곳에 작성하는 게 아니라, 객체의 상태(속성)와 행동(메서드)을 정해서, 코드만 보고도 인스턴스 객체의 기능을 단번에 알 수 있게 작성하는 것이 느슨한 결합을 추구하는 코드 작성법이다.

은닉화?
└▷ 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것.

⬜ 속성의 캡슐화

🎁 자바스크립트 getter/setter


⬜ 기능의 캡슐화

비슷한 기능을 하나의 객체에 모두 구현하려고 하는 경우, 하나의 클래스에 로직이 섞여서 객체가 지저분해 진다. 그러나 분리가 가능한 기능을 별도의 클래스 그룹으로 캡슐화하면 모듈화한 다른 기능은 우리가 원하는 기능만 선택해서 사용할 수 있다.


🟣 상속(Inheritance)

부모 클래스의 특징을 자식 클래스가 물려받는 것

더 자세하게는,

"기본 클래스(base class)의 특징을 파생 클래스(derived class)가 상속받는다"

라고 표현한다.

⬜ 상속(세로)

상위에 위치한 분류 계층을 하위분류 계층의 일반화라고 한다. 하위에 위치한 분류를 상위분류 계층의 특수화라고 한다.


⬜ 위임(가로)

그러나 무작정 상속을 받는 것에도 문제가 있다. 부모가 가지고 있는 속성 중 필요 없는 속성이 있을 수 있기 때문이다.

그림을 보면 프로펠러 비행기는 비행기의 일종으로서, 부모 클래스인 "비행기"의 모든 기능을 갖지만 단 한가지 스텔스 기능만은 보유하고 있지 않다.

스텔스 기능을 사용하지 않을 시 그냥 무시해도 되지만, 그렇게 되면 무결성 원칙에 어긋난다.


그럴 때 상속 대신 위임(가로)를 사용한다.

위임이란, 객체의 특정 기능을 수행하기 위해 다른 '클래스 그룹'을 생성하고, 이 '클래스 그룹'의 기능을 사용하기 위해 '클라이언트 클래스'가 연결을 맺은 구조이다.

우선 스텔스 클래스를 인자로 받는 비행기 클래스를 생성한다.

public class Airplane {
	StealthInterface stealth = null;
    public Airplane(StealthInterface stealth { // 생성자 함수
    	this.stealth = stealth;
    }
    
    // 메서드로도 StealthInterface 클래스를 저장할 수 있다.
    public void setStealthInterface(StealthInterface stealth){
    	this.stealth = stealth;
    }
    
    // StealthInterface 에 실행을 위임
    public void doingStealthFunction() {
    	stealth.doingStealthFunction();
    }
}

StealthInterface의 자식은 다음과 같다. 예시로 울트라 스텔스 기능만 책을 따라 적어보았다.

public interface StealthInterface {
	public void doingStealthFunction();
}

public class UltraStealth implements StealthInterface {
	@Override
    public void doingStealthFunction() {
    	System.out.println("울트라 스텔스 기능입니다.");
    }
}

이제 울트라 스텔스 기능이 부여된 비행기 객체를 생성하려면 다음과 같이 부르면 된다.

Airplane airplane = new Airplane(new UltraStealth());
airplane.doingStealthFunction(); // 울트라 스텔스 기능입니다.

사실 참고한 책을 따라 이해하기 위해 자바로 정리했지만, 자바스크립트에서 써먹히는 위임(가로)는 어떤 건지 따로 공부해봐야 겠다. 일단 구조라는 건 변치 않을테니 일단 복습만 해두었다...

당장 떠올려 보자면 지난 BeesBeesBees 과제에서 유충->벌->꿀벌/정찰벌 로 상속을 받던 구조가 생각난다.

비슷한 주제로 애벌레의 성장 과정을 상속으로 구현한다면, 애벌레는 변태를 하는 애벌레무변태/불완전 변태를 하는 애벌레가 있다.

이때 애벌레라는 부모 클래스변태() 메서드를 무작정 넣기 보다는, 별도의 클래스로 빼내어 변태() 부모클래스 아래 무변태(), 불완전 변태(), 완전변태() 자식 클래스로 분류하는 게 좋을 것 같다. 그런 다음 애벌레 부모 클래스에 위임(가로)하는 것이다.


🟣 추상화(Abstraction)

관련 된 다양한 데이터 중, 구현하려는 프로그램에 필요한 속성만 간추려 표현하는 것.

캡슐화가 '은닉'에 초점을 둔다면, 추상화는 '단순화'에 초점이 맞춰져 있다.

추상화를 통해 인터페이스가 단순해진다.

클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고, 단순한 이름으로 정의하는 것에 집중한다.

인터페이스?
클래스 정의 시, 메서드와 속성만을 정의한 것. 추상화의 본질이라고 볼 수 있다. (=부모클래스)


🟣 다형성(Polymorphism)

같은 클래스의 동일한 메소드를 호출할 때, 자식 클래스들이 저마다 다른 로직을 수행하고 리턴하는 것.

"동물" 이라는 객체가 있고, 그 안에 "말하다" 라는 메서드가 있다고 하자.

"동물"이라는 객체를 상속 받은 인스턴스들은 "오리", "강아지", "고양이" 등이 있다.

이때 세 가지의 동물들은 "말하다"라는 같은 메서드를 호출 하더라도, 종에 따라 제각기 다른 소리를 내야한다.

이게 바로 다형성이다.


⬜ 다형성이 없다면...

if(animal === 'duck')
  sayQuack();
else if(animal === 'dog')
  sayBow();
else if(animal === 'cat')
  sayMeow();

이렇게 하나하나 종류별로 분기 시켜 다른 함수를 만들어야 한다.
"말하다"라는 기능은 똑같은데, 소리가 다르다는 이유로 아예 별도의 함수를 여러 개 만들어야 하는 것이다.


⬜ 참고

🎁 자바스크립트에서의 다형성



profile
다 하자

0개의 댓글