Search
Duplicate
🚟

5. 객체지향 프로그래밍

개요

: 좋은 아키텍처를 만드는 작업은 객체 지향 설계 원칙을 이해하고 응용하는데서 출발한다.
⇒ 그렇다면 도대체 객체 지향이란 무엇인가?
⇒ 누군가는 데이터와 함수의 조합
→ o.f()가 f(o)와 다르다는 의미를 내포함, 말이 안 된다.
⇒ 누군가는 실제 세계를 모델링하는 새로운 방법
→ 도대체 실제 세계를 모델링한다는 것이 무엇을 의미하며 왜 우리는 그 방향성을 추구해야하는데?
⇒ 누군가는 캡슐화, 상속, 다형성을 바탕으로 객체 지향을 설명한다.
→ 이들은 객체지향이 이 세가지 개념을 적절하게 조합한 것이라고 한다.

캡슐화?

: 객체지향을 정의하는 요소 중 하나로 데이터와 함수를 쉽고 효과적으로 캡슐화하는 방법을 객체 지향 언어에선 제공한다.
데이터와 함수가 응집력있게 구성된 집단들을 각각 서로 구분 짓는 선을 그을 수 있다.
구분선 바깥에서 데이터는 은닉되고 일부 함수만이 외부에 노출된다.
이 개념들이 객체지향 언어에서는 private, public와 같은 접근 제한자로 표현된다.
: 하지만 객체지향 언어는 캡슐화에 과도하게 의존하지 않는다.
⇒ 객체지향 프로그래밍은 프로그래머가 충분히 올바르게 행동함으로써 캡슐된 데이터를 우회하여 사용하지 않을 것이라는 믿음을 기반으로 함

상속?

: 객체지향 언어는 캡슐화를 약화시켰지만 상속만큼은 확실하게 제공했다.
: 하지만 상속이란 단순히 어떤 변수와 함수를 하나의 유효 범위로 묶어서 재정의하는 일에 불과하다.
: 물론 그전의 언어들도 상속과 비슷해보이는 어떠한 기능을 제공하긴 했었다. 하지만 이는 눈속임에 불가
: 객체지향 언어에서는 상당히 편리하게 상속 기능을 제공함

다형성?

: getchar() 함수는 STDIN에서 문자를 읽는다. 그러면 DTDIN은 어떤 장치인가?
: putchar() 함수는 STDOUT으로 문자를 쓴다. 그런데 STDOUT은 또 어떤 장치인가?
: 이러한 함수는 다형적이다. 즉 행위가 STDIN과 STDOUT의 타입에 의존한다.
: 함수를 가리키는 포인터를 응용한 것이 다형성이다.
: 객체지향 언어는 다형성을 제공하지는 않지만 다형성을 좀 더 안전하고 더욱 편리하게 사용할 수 있게 해준다.
다형성이 가진 힘 - 새로운 장치의 등장
: 새로운 장치의 입출력 드라이버가 5가지 표준 함수를 구현한다면 장치에 상관않고 사용이 가능하다. 즉 입출력 드라이버가 프로그램의 플러그인화 된것
: 왜 유닉스 운영체제는 입출력 장치들을 플러그인 형태로 만드는 것인가? 프로그램은 장치에 독립적이어야 하기 때문이다.
: 플러그인 아키텍처는 입출력 장치의 독립성을 지원하기 위해 만들어졌고 등장 이후 거의 모든 운영체제에서 구현되었다.
: 객체지향의 등장으로 언제 어디서든 플러그인 아키텍처를 적용할 수 있게 되었다.
의존성 역전
: 위 함수에서 Main은 고수준 → 중수준 → 저수준 모듈을 차례로 호출한다. 즉 제어흐름은 소스 코드 의존성을 반드시 따른다.
: 하지만 다형성이 이 구조에 추가되면 특별한 일이 일어난다.
: 위 그림에서 HL1 모듈은 ML1 모듈의 F() 함수를 호출한다.(점선) 소스코드에서 HL1 모듈은 인터페이스를 통해 F() 함수를 호출한다.(실선)
: 이 인터페이스는 런타임에는 존재하지 않는다. HL1은 단순히 ML1을 호출할 뿐이다.
: 하지만 여기서 ML1과 인터페이스 사이의 소스 코드 의존성이 제어흐름과는 역전된다.
: 이러한 접근법을 사용한다면 객체 지향 언어로 개발된 시스템을 다루는 소프트웨어 아키텍트는 시스템의 소스 코드 의존성 전부에 대해 방향을 결정할 수 있다.
: 위 예시를 보면 UI와 Database는 Business Rules에 의존하게끔 소스코드 의존성을 부여하였다.
: 즉 UI와 Database가 Business Rules의 플러그인이 된다는 뜻으로 각각의 컴포넌트들은 독립적으로 동작하게 된다.
배포 독립성 - 컴포넌트의 소스 코드가 변경되면, 해당 코드가 포함된 컴포넌트만 다시 배포하면 된다.
개발 독립성 - 배포 독립성이 있으면,서로 다른 팀에서 각 모듈을 독립적으로 개발할 수 있다.

결론

: 객체 지향이란 다형성을 이용하여 전체 시스템의 모든 소스 코드 의존성에 대한 절대적인 제어 권한을 획득할 수 있는 능력이다.
: 객체 지향 언어를 사용하면 아키텍트는 플러그인 아키텍처를 구성할 수 있고, 고수준의 정책을 포함하는 모듈은 중, 저수준을 포함하는 모듈에 대해 독립성을 보장할 수 있다.
: 저수준의 세부사항은 중요도가 낮은 플러그인 모듈로 만들 수 있고, 고수준의 정책을 포함하는 모듈과는 독립적으로 개발하고 배포할 수 있다.