Javascript와 객체 지향 프로그래밍

객체 지향 프로그래밍 (OOP)

Javascript

지난 포스트인 Javascript와 객체 지향 프로그래밍 - 절차 지향 프로그래밍 & 객체 지향 프로그래밍 편에서 Javascript의 객체 지향에 대해 공부하면서 느꼈던 어려움과 절차지향과 객체지향에 대해 정리를 해보았습니다. 이번 포스트에서는 객체지향 프로그래밍이란 무엇인지 공부해보겠습니다.

객체 지향 프로그래밍 이란

이전 포스트에서 언급했듯이 객체 지향 프로그래밍이란 “누가 어떤 일을 할 것인가” 를 중심으로 구현된 프로그래밍 패러다임으로써, 다음과 같이 정리해볼수 있을거 같습니다.

  • 현실 세계의 개체를 기계의 부품처럼 하나의 객체로 만들어, 기계적인 부품들을 조립하여 제품을 만들듯이 소프트웨어를 개발할 때에도 객체들을 조립해서 작성할 수 있도록 하는 기법이다.
  • 객체 지향의 “객체”는 현실 세계의 사물을 나타내는데 각 객체는 자신의 정보를 가지고 있는 독립적인 개체(Entity)로써 각각의 성격을 띄고 있으며 이 객체가 유기적으로 상호작용 하여 작게는 하나의 기능, 크게는 하나의 어플리케이션을 프로그래밍 하는 방법이다.

그렇다면 객체 지향 프로그래밍의 “객체”의 기본 구성 요소는 무엇일까?

기본 구성요소

위에서 언급했듯이 OOP의 객체(object)는 현실 세계의 사물을 나타낸다고 했다. 즉, 현실 세계의 사물은 각각의 동작(기능)과 상태를 가지고 있으며 여러 동작은 유기적으로 움직이며 상호간 침범하지 않도록 또는 방해되지 않도록 설계되어 있다고 설명할 수 있다. 대표적인 예로 사람 이다.

OOP의 기본 구성요소를 설명하기 전에 현실 세계의 사물을 먼저 정의한 이유는 OOP의 기본 구성요소 또한 같기 때문이다.

1) 클래스 (class)

클래스란 1개 이상의 유사 객체의 공통된 특성(속성과 메서드)을 데이터 추상화 과정을 통해 구현한 하나의 틀(template)로써, 객체지향 프로그램의 기본적인 사용자 정의 데이터형(user defined data type)이라고 할 수 있다.

  • 다른 클래스 또는 외부 요소와 독립적으로 디자인하여야 한다.
  • 클래스에 의해 생성된 새로운 객체(object)를 클래스의 인스턴스라 하며, 클래스로부터 새로운 객체를 생성하는 것을 인스턴스화 라고 한다.
  • 최상위 클래스 또는 메타 클래스는 상위 클래스를 갖지 않는 유일한 클래스로 클래스 계층 트리의 최상단에 위치하는 클래스이며, 슈퍼 클래스는 특정 클래스의 상위 클래스이고, 서브 클래스는 특정 클래스의 하위 클래스이다.

2) 객체 (object)

클래스의 인스턴스를 객체(object)라고 하며 필요한 속성(Attribute)과 속성을 처리하기 위한 메서드(Method)를 가진 하나의 소프트웨어 모듈이며 다른 객체들과 구별될 수 있는 이름이 있고, 실제 메모리상에 할당된 것으로 실제 프로그램에서 사용되는 데이터이다.

속성(Attribute)
  • 객체가 가지고 있는 정보 또는 상태를 나타내며 객체의 속성, 데이터, 변수, 상수 또는 자료구조라고도 부른다.
메서드(Method)
  • 객체가 가진 기능으로 객체의 속성을 처리하는 하나의 알고리즘이다.
  • 객체가 메시지를 받아 실행해야 할 객체의 구체적인 연산을 정의한 것, 전통적 시스템의 함수(Function)나 프로시저(Procedure)에 해당하는 연산 기능을 수행한다.
  • 메소드는 다른 객체로부터 메시지를 받았을 때 수행하게 된다.

3) 메시지 (message)

메시지는 객체 간의 상호작용을 하는 데 사용되는 수단으로, 객체에게 어떤 행위를 하도록 지시하는 명령 또는 요구 사항이다.
클래스로부터 생성된 객체를 사용하는 방법으로서 객체에 명령을 내리는 것이 메시지라 할 수 있다.

  • 메시지의 구성 요소 : 메시지를 받는 객체의 이름, 객체가 수행할 메소드 이름, 메소드를 수행할 때 필요한 인자
  • 메시지를 받은 수신 객체는 요구된 메소드를 수행하여 결과를 반환하게 된다.

OOP 기법 (특성)

객체 지향 프로그래밍이란 “누가 어떤 일을 할 것인가” 이며 1개 이상의 유사 객체의 공통된 특성(속성과 메서드) 가진 클래스를 통해 객체를 생성하고 상호 유기적으로 메시지를 주고 받으며 결과를 반환한다고 정리해볼 수 있으며 OOP의 기법 및 특성이 모두 담겨져 있다.

1) 캡슐화 (Encapsulation)

  • 자료 부분과 연산(또는 함수) 부분 등 정보처리에 필요한 기능을 한 테두리로 묶는 것
  • 연관된 데이터와 함수를 함께 묶어 외부와 경계를 만들고 필요한 인터페이스만을 밖으로 드러내는 과정
  • 객체지향 기법의 정보 은닉 과 밀접한 기법
  • 장점
    • 높은 재사용성
    • 인터페이스의 단순화
    • 변경 또는 수정이 발생할때 오류의 파급효과가 적음
    • 응집력이 향상됨

2) 은닉화 (Information Hiding)

  • 캡슐화에서 가장 중요한 개념으로, 다른 객체에게 자신의 정보를 숨기고 자신의 연산만을 통하여 접근을 허용하는 것
  • 정보 은닉은 고려되지 않은 영향(side effect)들을 최소화함을 목적으로 함
  • 따라서, 외부 객체가 접근하거나 사용하지 못하므로 유지보수와 소프트웨어 확장 시 오류를 최소화 할 수 있음

3) 추상화 (Abstraction)

  • 자료 추상화는 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단히 만드는 것으로, 모델화하는 것을 의미
  • 자료 추상화를 통해 정의된 자료형을 추상 자료형이라고 함
  • 추상 자료형은 자료형의 자료 표현과 자료형의 연산을 캡슐화한 것으로 접근 제어를 통해서 자료형의 정보를 은닉할 수 있다.
  • 객체 지향 프로그래밍에서 일반적으로 추상 자료형을 클래스, 추상 자료형의 인스턴스를 객체, 추상 자료형에서 정의된 연산을 메소드(함수), 메소드의 호출을 생성자라고 한다.

4) 상속성 (Inheritance)

  • 상속은 새로운 클래스가 기존의 클래스의 자료와 메서드를 이용할 수 있게 하는 기능
  • 상속을 받는 새로운 클래스를 부클래스, 파생 클래스, 하위 클래스, 자식 클래스라고 하며 새로운 클래스가 상속하는 기존의 클래스를 기반 클래스, 상위 클래스, 부모 클래스라 함
  • 상속을 통해서 기존의 클래스를 상속받은 하위 클래스를 이용해 프로그램의 요구에 맞추어 클래스를 수정할 수 있고, 클래스 간의 종속 관계를 형성함으로써 객체를 조직화할 수 있다.
  • 다중 상속
    • 클래스가 2개 이상의 클래스로부터 상속받을 수 있게 하는 기능
    • 클래스들의 기능이 동시에 필요할 때 용이하나 클래스의 상속 관계에 혼란을 줄 수 있음 (예: 다이아몬드 상속)
    • 프로그래밍 언어에 따라 사용 가능 유무가 다르므로 주의해서 사용해야 한다. JAVA는 지원하지 않음

5) 다형성 (Polymorphism)

  • 상이한 클래스들이 동일한 메서드명을 갖는 것 또는 한 메시지가 객체에 따라 다양한 방식으로 응답할 수 있는 것을 의미함
  • 일반적으로 오버라이딩이나 오버로딩을 의미함
    • 오버라이딩: 같은 이름의 메소드가 여러 클래스에서 다른 기능을 하는 것
    • 오버로딩: 같은 이름의 메소드가 인자의 개수나 자료형에 따라서 다른 기능을 하는 것
  • 다형 개념을 통해서 프로그램 안의 객체 간의 관계를 조직적으로 나타낼 수 있음

6) 연관성 (Relationship)

관계성의 종류 의미 특성
is-member-of 연관화 링크 개념과 유사
is-instance-of 분류화 객체 및 클래스의 인스턴스를 표현
is-part-of 집단화 상향식, 단일 상속, 복합 객체 (composite object) 표현에 유용
is-a 특수화, 일반화 하향식, 다중 상속, 복잡한 객체 표현에 유용
  • 두 개 이상의 엔티티 형에서 데이터를 상호 참조하는 클래스간의 연관관계를 정의
  • 객체간의 관계를 세부적으로 정의하여 구현 용이
  • 관계성의 종류
    • is-member-of (연관화, association)
      • 공통된 의미(semantic)를 서로 연관된 집단으로 표현하는 방법으로 링크(link)와 그 의미가 유사
      • 객체들의 물리적, 또는 개념적 연결을 두 개 이상의 객체와 클래스로 표현
      • 즉, 연관화는 관련되지 않은 클래스들간의 의미적 연결
    • is-instance-of (분류화, classification)
      • 공통된 속성에 의하여 정의된 객체 및 클래스에 있어 구성원들의 인스턴스
      • 즉, 분류화는 동일한 형의 특성을 갖는 객체들이 모여 클래스를 구성하는 것
        • 여기서, 클래스는 객체들의 본질에 대한 추상화
    • is-part-of (집단화, aggregation)
      • 서로 관련 있는 여러 개의 객체를 묶어 한 개의 상위 객체 생성
      • 여러 개의 속성을 묶어 사용자 정의형의 엔티티를 만드는 수단으로 사용
      • 한 객체에서 하나 이상의 객체는 사용자 표정의 형이 될 때 복합 객체(composite object)
        • 즉, 복합 객체의 종속 성분을 모델링하기 위해 사용되며, 이들 복합 성분 클래스 관계를 통해 복합 속성 계층(composite attribute hierarchy)을 형성
    • is-a
      • 일반화 (generalization)
        • 일반화는 객체들에 있어 공통적인 성질들을 상위 객체로 정의하고, 특수화(specialization)된 객체들을 하위의 부분형(subtype) 객체로 정의
      • 특수화 (specialization)
        • 일반화와 개념과 같으나, 클래스를 보는 시점에 있어 상위의 클래스에서 하위의 클래스를 보는 관점(특수화의 역은 일반화)
        • 하위 개념으로 내려 갈수록 인스턴스는 특수화
        • 클래스로 모델화되는 실세계 객체들을 겹치지 않는 서브 클래스로 나누거나 상이한 실세계 상황으로 나누기 위해 사용

OOP 장단점

1) 장점

  • 자연적인 모델링이 가능함
  • 코드의 재사용성 증가
  • 소프트웨어의 유지보수성 향상
  • 대형 프로젝트 개발에 적합

2) 단점

  • 처리속도가 상대적으로 느림
  • 다중 객체 생성에 따른 메모리 사용량 증가
  • 객체 설계의 복잡도에 따른 설계시간 소용 시간

강한 응집력 (Strong Cohesion)과 약한 결합력 (Weak Coupling)

위의 장점들을 관통하는 객체 지향 프로그래밍의 중요한 특성은 강한 응집력(Strong Cohesion)과 약한 결합력(Weak Coupling) 을 지향한다는 점이다. 소프트웨어 공학에서 말하는,

응집력(cohesion)

  • 프로그램의 한 요소가 해당 기능을 수행하기 위해 얼마만큼의 연관된 책임과 아이디어가 뭉쳐있는지를 나타내는 정도.
  • 프로그램의 한 요소가 특정 목적을 위해 밀접하게 연관된 기능들이 모여서 구현되어 있고, 지나치게 많은 일을 하지 않으면 그것을 응집력이 높다고 표현함.

결합력(coupling)

  • 프로그램 코드의 한 요소가 다른 것과 얼마나 강력하게 연결되어 있는지, 얼마나 의존적인지를 나타내는 정도.
  • 결합력이 낮다는 것은 한 요소가 다른 요소들과 관계를 크게 맺고 있지 않은 상태를 의미함.

OOP의 경우 클래스에 하나의 문제 해결을 위해 데이터를 모아 놓은 객체를 활용한 프로그래밍을 지향하므로 응집력을 강화하며, 클래스 간에 독립적으로 디자인함으로써 결합력을 약하게 할 수 있다.

마치며

사실 자바스크립트를 사용하면서 OOP에 대한 기술부채가 있었고, Javascirpt의 Prototype 기반의 객체지향 설계 및 구현과 같은 자료를 읽어도 근본이 되는 OOP에 대한 단순 암기식 지식 때문인지 이해는 되지만 시원하지 않았다. 그러나 이번 포스트를 쓰기 위해 공부하고 작성하는 동안 어플리케이션 전체를 그리고 그 내부의 세부 기능을 설계와 구현의 관점에서 OOP가 어떻게 바라보는지 이해할 수 있었다. 다음 포스팅은 Prototype 기반의 Javascript 객체지향 에 대해서 작성해보겠습니다.


참고