Chapter 5: 객체지향 디자인

이 장에서 배울 내용

  • 객체지향 프로그램 디자인
  • 다양한 객체 사이의 관계를 정의하는 방법
  • 추상화의 중요성과 이를 디자인에 활용하는 방법

객체지향 철학

절차형 접근 방식(C)는 ‘이 프로그램이 무슨 일을 하는가?’라는 질문을 토대로 접근하는 데 반해 객체지향 접근 방식은 ‘현실세계의 어떤 대상을 모델링하는가?’라는 관점에서 접근합니다.

클래스

어떤 대상의 유형을 정의합니다. 이 클래스에 속하는 구체적인 대상을 객체object 혹은 인스턴스instance라 합니다.

예를 들어 오렌지는 ‘나무에서 자라고 / 주황색을 띄고 / 독특한 향과 맛을 내는 과일의 한 종류’라고 클래스의 관점에서 속성들을 정리하여 나타낼 수 있습니다. 이 때 ‘내가 지금 먹고 있는 오렌지’와 같이 구체적인 대상이 객체가 됩니다.

또다른 예로 주식종목 추천 애플리케이션을 구현할 때 OOP 관점에서 ‘주식시세’는 추상적인 개념(시세)를 정의하는 클래스로 볼 수 있습니다. 이 때 ‘마이크로소프트사의 현재 주식시세’는 ‘시세’ 클래스에 속하는 인스턴스(객체)가 됩니다.

컴포넌트

절차지향 프로그래밍에서 복잡한 작업을 작은 프로시저procedure 단위로 쪼개는 것처럼 OOP에서는 클래스를 더 작은 컴포넌트component 단위로 나눕니다.

속성

속성property는 객체의 톡성을 표현합니다. 앞서 예를 든 주식시세 클래스를 다시 보자면 각 객체는 ‘회사 이름, 종목 번호, 현재 가격’등의 속성을 가지고 있을 것 입니다.

동작

*동작behavior는 객체가 하는 일 혹은 객체로 할 수 있는 일을 표현합니다. 클래스에서는 클래스 메서드로 구현되겠네요.

객체 관계

has-a 관계와 is-a 관계에 대한 이야기입니다.

has-a 관계

한 객체가 다른 객체를 포함하는 관계입니다. 꼭 상속 관계일 필요는 없고 nested class나 변수로 포함하고 있을 수도 있겠네요.

is-a 관계

대체로 상속으로 나타내지는 관계입니다. 베이스 클래스가 공통 기능/속성을 가지고 있고 이를 상속 받는 서브 클래스가 조금 더 구체적으로 이를 오버라이드override하거나 새로운 기능/속성을 추가해서 사용합니다.

다형성

다형성polymorphism은 OOP가 가지는 특징 중 하나입니다. 베이스 클래스에서 eat()이라는 메서드를 선언했다면, 이 베이스 클래스에서 파생된 서브 클래스들은 각자 eat() 메소드를 오버라이드해서 구현할 것입니다. 사용자는 단순히 eat() 메서드를 실행하기만 하면 각 객체의 클래스에 따라 구현된 eat()이 실행될 겁니다.

다중 상속

꼭 클래스가 하나의 부모 클래스를 상속 받을 필요는 없습니다. 필요하다면 다중 상속을 통해 베이스 클래스를 여러 개 둘 수도 있습니다. 다만 이러한 다중 상속은 머리를 꽤나 아프게 하기 때문에 사용하기 전 정말 필요한지 한번쯤 더 고려해봐야합니다.

믹스인 클래스

C++에서 다중 상속과 문법은 같지만 의미가 조금 다릅니다.

믹스인 클래스는 ‘이 클래스가 할 수 있는 일이 또 뭐가 있나?’ 란 질문에 ‘~도 할 수 있다`라고 답하는 역할을 한다. 믹스인 클래스는 is-a 관계를 완전히 구현하지 않고도 기능을 추가할 때 사용한다. 일종의 공유 관계라 볼 수 있다.

믹스인 클래스는 추가 기능을 구현하는데 필요한 속성/메서드만을 제한적으로 가지고 있기 때문에 일반적인 다중 상속보다 사용하기 쉽습니다.

추상화

추상화의 핵심은 인터페이스interface구현implementation을 분리하는데에 있습니다.

public으로 선언된 인터페이스는 작게는 프로그램 내의 다른 컴포넌트에서, 크게는 해당 프로그램/라이브러리의 사용자가 사용하게 되는 만큼 많은 부분을 고려해서 반영하여야합니다. 한번 배포된 인터페이스를 고치는 일은 내부 구현을 변경하는 일보다 훨씬 많은 작업을 요구합니다. (Python2 -> Python3의 문법 변화가 얼마나 많은 파이썬 코드를 변경시켰을까요?)

Back to 전문가를 위한 C++ (Professional C++) 작성 포스트 모음