엄범


객체 지향

객체지향 패러다임을 사용할 때, 개발 대상을 물리적 또는 추상적 대상에 비유하는 것이 도움이 된다.

유즈케이스 다이어그램을 그린다거나, 시나리오를 분석하여 클래스를 추출하는 작업을 진행하는 등.


객체 지향의 장점

  • 캡슐화, Encapsulation
    • 크게 2가지로 나눠볼 수 있음. 로직+데이터 묶음 / 정보 은닉
    • 정보 은닉이란, public으로 공개할 API들만 공개하고, 실제 로직은 비공개로 처리하여 구현과 API를 깔끔히 분리.
    • 서로의 내부 구현에 연연하지 않기 때문에 의존성이 내려간다.
  • 추상화, Abstraction
    • layer 개념을 통해서 체계적으로 구조화 할 수 있음. (절차지향도 추상화가 가능은 한데... 캡슐화/상속과 맞물려서 추상화가 더 용이하지 객체지향에서는....)
  • 상속, Inheritance
    • 실세계의 계층 관계 표현, 코드 재사용성, 유지보수성, 코드를 DRY하게.
  • 다형성, Polymorphism
    • 한 마디로 "상위 타입 변수에 하위 타입을 담을 수 있는 것"을 의미. 
    • 동물원에넣다(사자 x),  동물원에넣다(고양이 x)처럼 써야 했던 것을 동물원에넣다(동물 x)와 같이 쓸 수 있게 되니 일단 코드가 DRY해지고, 인터페이스를 이용해 결합도를 낮추거나 하는게 가능해진다.

객체 지향 5대 원칙

SOLID
  • SRP 단일 책임의 원칙
  • OCP 개방 폐쇄의 원칙
  • LSP 리스코프 치환의 원칙
    • 다형성을 나타내는 말인데, 상속해서 하위 타입이면 상위 타입 변수로 치환될 수 있다. 뭐 이런 의미라고 보면 된다.
  • ISP 인터페이스 분리 원칙
  • DIP 의존성 역전 원칙
*** 근데 이런 학문적인 정의보단... 직접 체감하는게 중요할 것 같다.


응집도 ( Cohension ) 와 결합도 ( Coupling )

  • 응집도 (Cohension)
    • 하나의 모듈(클래스) 내의 구성 요소들 사이의 기능적 관련성
    • 즉 한 모듈이 쓸데없는 기능 없이 목표하는 기능만 가지고 있는지.
    • 높을 수록 좋다.
  • 결합도 (Coupling) = 의존성 (dependency)
    • 어떤 모듈과 다른 모듈 간의 의존성 (dependency)을 의미
    • 낮을 수록 좋다. 디커플링 해야 한다고 자주 얘기 나오지.
    • 모듈을 독립적으로 짜야 수정할 때 영향이 적다. 독립적으로 짠다는건, 다른 모듈과의 의존성을 최대한 없앤다는걸 의미한다.

```
기능적 응집 / 순차적 응집 / 교환적 응집 / 절차적 응집 / 시간적 응집 / 논리적 응집 / 우연적 응집
```
앞쪽으로 갈 수록 응집도가 크다. 


Relationship

```

A is B   : extents

A has B : Aggregation (약한 연관)

A has B : Composition (강한 연관)

```

Aggregation

  • Person과 Address
  • HistoryClass와 Student
  • A와 B가 서로의 존재에 별 상관 없이 독립적으로 존재
  • 전체와 부분의 연관 관계를 맺지만, 동일한 생명 주기를 갖지는 않는다. (Address가 없는 사람도 있을 수 있음)
UML aggregation

Compoistion

  • Car와 Engine
  • House와 Room
  • B가 A 내부가 아닌 다른 곳에서는 어떤 의미도 갖지 못하는 경우.
    • 강한 연관. B가 A의 핵심 부속품인 경우.
  • 전체와 부분이 강한 연관 관계를 맺으며, 같은 생명 주기를 가진다.

UML composition


Decorator ( Wrapper )

Decorator는 Delegation을 사용한 여러가지 방법 중에 하나라고 생각하면 된다. 그러니까 Decorator가 더 세부적인 개념.

Delegation은 책임 전가의 느낌이 강하고, Decorator는 기능 추가의 느낌이 강하다.

객체 지향에서는 "책임"이 상당히 중요한데, 모듈의 책임을 명확히 하지 않으면 특정 기능의 코드가 여기저기 산재해서 존재할 수도 있고... 그럼 유지보수도 어렵고 디버깅도 어려워진다. 이 클래스가 맡아서 처리할 부분을 명확히 해주어야 함.


delegate는 함수 포인터(또는 함수 포인터들의 컨테이너)를 의미하기도 하고, 코틀린의 ``kt by``키워드 처럼 프로퍼티(객체)를 위임하는 것을 의미하기도 한다.


1. 콜백 메서드에 콜백으로 실행할 함수 포인터가 넘어가면 콜백 메서드 내부에서는 그 함수 포인터(delegate 변수)를 이용해 함수를 실행하게 된다.


2. 2017/12/02 - [Coding Syntax/Kotlin Java] - [Kotlin] by : Decorator & Delegation



동적 디스패치 / 정적 디스패치

  • 동적 디스패치
    • 객체의 동적 타입에 따라 적절한 메소드를 호출해 주는 방식이 
    • 즉, 실제로 할당된 객체에 연결된 메소드를 호출해준다.
  • 정적 디스패치
    • 컴파일 시점에 어떤 메소드가 호출될지를 결정
    • 즉, 컴파일 타임에 결정된 객체의 타입에 연결된 메소드를 호출해준다.


  • 자바에서는 구현클래스를 참조하게 되면 정적 디스패치한다. (바이트코드에 어떤 클래스의 어떤 메서드를 호출하겠다. 라는 것이 드러난다.)
  • 반면 인터페이스를 참조하게 되면 동적 디스패치한다. 런타임에 어느 메서드를 부를지 결정한다는 것.


대부분의 객체지향 언어에서 같은 클래스에 속한 객체는 같은 메소드 테이블을 공유한다.

그래서 메소드 테이블은 클래스마다 하나씩만 만들어 두고, 각 객체는 자신의 클래스에 대한 참조를 통해 그 메소드 테이블을 참조하는 방식을 많이 사용한다.


그러나 동적 디스패치를 처리할 때는 대체로 객체별로 자신의 메소드에 대한 테이블을 저장하는 방법을 사용한다.