[Java] 객체 지향

어정윤·2021년 1월 24일
0

Java 스터디

목록 보기
5/12
post-thumbnail

[Java] 객체 지향

1. 객체 지향이란

객체지향의 목표는 실세계를 모방하는 것이 아닌 새로운 세계를 창조하는 것이다.

객체를 스스로 생각하고 스스로 결정하는 현실 세계의 생명체에 비유하는 것은 상태와 행위를 '캡슐화'하는 소프트웨어 객체의 '자율성'을 설명하는 데 효과적이다. 현실 세계의 사람들이 암묵적인 약속과 명시적인 계약을 기반으로 목표를 달성해 나가는 과정은 '메시지'를 주고받으며 공동의 목표를 달성하기 위해 '협력'하는 객체들의 관계를 설명하는 데 적합하다.

객체지향이란

  • 시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법이다.
  • 자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.
  • 객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할을 관련된 책임의 집합이다.
  • 객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메소드를 자율적으로 선택한다.

2. 객체 지향의 이해

2-1. 역할

역할은 관련성 높은 책임의 집합이다. 객체의 역할은 사람의 역할과 유사하게 다음과 같은 특징을 가진다.

  • 여러 객체가 동일한 역할을 수해할 수 있다.
  • 역할은 대체 가능성을 의미한다.
  • 각 객체는 책임을 수행하는 방법을 자율적으로 선택할 수 있다.
  • 하나의 객체가 동시에 여러 역할을 수행할 수 있다.

역할은 협력 내에서 다른 객체로 대체할 수 있음을 나타내는 일종의 표식이다. 협력 안에서 역할은 "이 자리는 해당 역할을 수행할 수 있는 어떤 객체라도 대신할 수 있습니다."라고 말하는 것과 같다.

역할을 대체하기 위해서는 각 역할이 수신할 수 있는 메시지를 동일한 방식으로 이해해야 한다.

역할은 객체지향 설계의 단순성, 유연성, 재사용성을 뒷받침하는 핵심 개념이다.

역할의 대체 가능성은 행위 호환성을 의미하고, 행위 호환성은 동일한 책임의 수행을 의미한다.

2-2. 책임

책임이란 객체가 어떤 행동을 하라고 다른 객체로부터 요청을 수신했을 때 요청을 처리하기 위해 객체가 수행하는 행동이다.
즉, 메시지를 수신받았을 때 그 메시지의 요청을 처리하기 위해 하는 행동이다.

객체의 책임은 크게 두 가지 범주로 분류된다.

  • 하는 것
    • 객체를 생성하거나 계산을 하는 등의 스스로 하는 것
    • 다른 객체의 행동을 시작시키는 것
    • 다른 객체의 활동을 제어하고 조절하는 것
  • 아는 것
    • 개인적인 정보에 대해 아는 것
    • 관련된 객체에 대해 아는 것
    • 자신이 유도하거나 계산할 수 있는 것에 대해 아는 것

메시지는 객체로 하여금 자신의 책임, 즉 행동을 수행하게 만드는 유일한 방법이다. 메시지를 처리할 수 있다는 것은 객체가 해당 메시지에 해당하는 행동을 수행할 책임이 있다는 것을 의미한다. 따라서 메시지의 개념은 책임의 개념과 연결된다.

2-3. 협력

객체의 세계에서는 협력이라는 문맥이 객체의 행동 방식을 결정한다. 중요한 것은 개별 객체가 아니라 객체들 사이에 이루어지는 협력이다.

객체가 다른 객체에게 주어진 책임을 수행하도록 요청을 보내는 것을 메시지 전송이라고 한다. 따라서 두 객체 간의 협력은 메시지를 통해 이루어진다.

객체 지향 설계는 협력에 참여하기 위해 어떤 객체가 어떤 책임을 수행해야 하고 어떤 객체로부터 메시지를 수신할 것인지를 결정하는 것으로부터 시작된다. 어떤 클래스가 필요하고 어떤 메소드를 포함해야 하는지를 결정하는 것은 책임과 메시지에 대한 대략적인 윤곽을 잡은 후에 시작해도 늦지 않다.

3. 객체 지향 프로그래밍의 특징

3-1. 추상화(Abstraction)

  • 객체들의 공통적인 특징(기능, 속성)을 도출하는 것
  • 객체 지향적 관점에서는 클래스를 정의하는 것을 추상화라고 할 수 있다.
    (클래스가 없는 객체 지향 언어도 존재 ex. JavaScript)

3-2. 캡슐화(Encapsulation)

  • 실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있다.
  • 객체가 독립적으로 역할을 할 수 있도록 데이터와 기능을 하나로 묶어 관리하는 것
  • 코드가 묶여있어서 오류가 없어 편리하다.
  • 데이터를 보이지 않고 외부와 상호작용을 할 때는 메소드를 이용하여 통신을 한다. 보통 라이브러리로 만들어서 업그레이드해 사용할 수 있다.

3-3. 상속성(Inheritance)

  • 하나의 클래스가 가진 특징(함수, 데이터)을 다른 클래스가 그대로 물려받는 것
  • 이미 작성된 클래스를 받아서 새로운 클래스를 생성하는 것
  • 기존 코드를 재활용해서 사용함으로써 객체 지향 방법의 중요한 기능 중 하나에 속한다.

3-4. 다형성(Polymorphism)

  • 약간 다른 방법으로 동작하는 함수를 동일한 이름으로 호출하는 것
  • 동일한 명령의 해석을 연결된 객체에 의존하는 것
  • 오버라이딩(Overriding), 오버로딩(Overloading)
    • 오버라이딩(Overriding) : 부모 클래스의 메소드와 같은 이름을 사용하며 매개변수도 같되, 내부 소스를 재정의하는 것
    • 오버로딩(Overloading) : 같은 이름의 함수를 여러 개 정의한 후 매개변수를 다르게 하여 같은 이름을 경우에 따라 호출하여 사용하는 것
  • 다형성은 메시지 수신자의 종류를 캡슐화한다.

4. 정리

객체 지향의 기본 개념은 책임을 수행하는 자율적인 객체들의 협력을 통해 애플리케이션을 구축하는 것이다. 객체지향의 세계에서 객체들이 서로 협력하기 위해 사용할 수 있는 유일한 방법은 메시지를 전송하는 것이다.

객체지향 애플리케이션의 중심 사상은 연쇄적으로 메시지를 전송하고 수신하는 객체들 사이의 협력 관계를 기반으로 사용자에게 유용한 기능을 제공하는 것이다.

클래스 기반의 객체 지향 언어를 사용하는 대부분의 사람들은 객체 지향 애플리케이션을 클래스의 집합으로 생각한다. 프로그래머 입장에서 클래스는 실제 볼 수 있고 수정할 수 있는 구체적인 존재다. 그러나 클래스는 단지 동적인 객체들의 특성과 행위를 정적인 텍스트로 표현하기 위해 사용할 수 있는 추상화 도구일 뿐이다. 중요한 것은 클래스가 아니라 객체다. 클래스를 정의하는 것이 먼저가 아니라 객체들의 속성과 행위를 식별하는 것이 먼저다. 클래스는 객체의 속성과 행위를 담는 틀일 뿐이다.

객체 지향 설계의 중심에는 메시지가 위치한다. 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 된다. 메시지가 객체를 선택하게 만드려면 메시지를 중심으로 협력을 설계해야 한다.

책임-주도 설계란 책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법을 말한다.
책임-주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. 즉, '어떻게'가 아닌 '무엇을'을 먼저 생각하는 것이다.
이 과정을 흔히 What/Who 사이클이라고 한다.

결론적으로 협력이라는 문맥 안에서 필요한 메시지를 먼저 결정한 후에 메시지를 수신하기에 적합한 객체를 선택한다. 그리고 수신된 메시지가 객체의 책임을 결정한다.

협력이라는 문맥 안에서 객체의 책임을 결정하는 것은 메시지다. 책임이 먼저 오고 객체가 책임을 따른다. 결과적으로 시스템이 수행해야 하는 전체 행위는 협력하는 객체들의 책임으로 분배된다.

객체가 자신이 수신할 메시지를 결정하게 하지 말고 메시지가 협력에 필요한 객체를 발견하게 해야 한다.

profile
성장ing

0개의 댓글