객체와 속성
객체(object)란 필요한 자료 구조와 이에 수행되는 함수들을 가진 하나의 독립된 존재입니다. 각 객체가 자료 구조를 갖는다는 것은 각 객체가 어떤 속성(attribute)을 가지고 있다는 것을 의미합니다. 예를 들어, 그래픽 프로그램에서 하나의 점을 객체로 본다면 수평과 수직 위치가 자료이면서 그 값이 객체의 속성을 의미합니다. 각 객체가 적용될 수 있는 연산(operation)을 갖는다는 것은 각 객체가 어떤 연산을 수행할 수 있는 능력(behavior)을 갖추고 있다는 것을 의미합니다.
객체는 하나의 변수나 자료 구조와는 구별됩니다. 예를 들어, 'int X;' 라고 프로그램에서 정의된 X는 하나의 정수를 보관하는 장소를 가질 뿐, X 자체가 어떤 연산을 수행할 수는 없습니다.
모델링 할 때 어떤 개념이 객체인지 속성인지 결정하기가 어려운 일입니다. 예를 들어 '색깔'이 자동차의 색상으로 쓰일 때는 속성이지만 색상을 여러 가지 방법으로 사용하는 그래픽 편집기에서는 클래스가 되는 점입니다. 또 다른 예로 빌딩의 경우도 학과의 건물로 사용될 때는 속성이지만 빌딩 관리 시스템에서 사용될 때는 객체가 됩니다.
객체는 복합적인 속성을 가진 독립적인 존재지만 속성은 단일 값을 가지며 독립적인 존재가 아닙니다.
독립적인 존재라는 뜻은 애플리케이션이 객체에 대한 정보나 상태를 관리하고 유지보수 할 만한 것이라는 의미합니다. 예를 들어 '좌석의 수'는 자동차 또는 강의실, 비행기 내의 좌석 수를 의미하는 것으로 독립적인 존재는 아닙니다. 물리적으로 독립적인 존재만이 아니라 개념적으로도 분리, 독립된 존재이여야 합니다.
속성은 입력 장치를 통하여 입력할 수 있으나 객체는 불가능합니다. 객체는 복합적인 존재이므로 생성자를 호출함으로써 생성됩니다. 예를 들어 학생이라는 의미의 Student 객체를 생각해 봅시다. Student 객체는 키보드 입력으로 만들 수 없습니다. 학생의 이름, 학번, 주소, 전화번호, 기타 정보는 입력할 수 있습니다. 이런 것은 모두 속성이라고 합니다. 하지만 Student 객체는 생성자를 불러야 만들 수 있습니다.
캡슐화
객체의 속성 부분과 오퍼레이션 부분을 하나로 모아서 캡슐화 한다는 개념은 여러 가지 작은 알약을 캡슐로 싸서 만든 하나의 약과 같은 개념입니다. 즉 연관된 여러 항목을 모아서 그 둘레에 캡슐을 씌워 하나로 취급하는 것입니다. 소프트웨어 설계에서 어떤 데이터와 어떤 함수는 매우 연관되어 있습니다.
예를 들면 대학 학사관리 시스템에서 학생들의 학번, 이름, 주소 등의 속성과 학생에 관련된 작업을 처리하는 오퍼레이션 즉 평점 계산, 주소 변경, 수강 신청 등은 하나로 묶는 것이 자연스럽다. 즉 학생에 관련된 정보와 이의 처리에 필요한 작업을 하나로 묶는 개념이 캡슐화(encapsulation)입니다.
캡슐화는 설계나 분석 단계에 주어진 문제를 간단히 생각하는 추상화의 수단이 될 수도 있습니다, 즉 데이터를 이루는 객체의 속성, 오퍼레이션 등의 세부 사항은 차후에 생각하고 처음에는 객체라는 덩어리 단위로 개괄적으로 생각 하는데 도움이 됩니다.
캡슐 속에 있는 항목에 대한 정보를 외부에 감추는 것을 정보 은닉(infor- mation hiding)이라 합니다. 정보가 외부에 은폐되었다는 것은 자료 구조와 함 수에 사용된 알고리즘을 외부에서 직접 접근하여 사용하거나 변경하지 못하게 하는 것을 말합니다. 즉 하나의 블랙박스가 되는 것입니다.
캡슐화 된 정보는 외부에 보이지 않도록 감추어질 수도 있고 필요에 따라 보이게 할 수도 있습니다. 클래스는 구현에 따라 객체의 오퍼레이션과 속성을 캡슐화 된 외부에 감출 수도 있고 보이게 할 수도 있습니다. 객체지향 언어의 public, private, protected가 바로 캡슐 안의 접근을 제어하기 위한 문법들입니다
연관
객체는 일반적으로 홀로 동작하지 않습니다. 객체지향 시스템에서 객체는 다른 객체가 제공하는 서비스를 실행시키는 메시지를 보내어 상호작용함으로써 역할을 담당합니다. 메시지를 받은 객체는 요청된 서비스나 메소드를 구동시켜 그 결과를 보냅니다. 서비스를 제공하는 객체(이를 서버라 부름)와 서비스를 요청하는 객체(이를 클라이언트라 부름)가 상호작용하는 관계는 앞서 설명한 캡슐화의 결과입니다.
어떤 객체가 다른 객체에 있는 서비스를 호출한다면 두 객체가 속하는 클래스는 서로 연관(association) 관계에 있다고 말할 수 있습니다. 시스템의 모든 객체가 다른 모든 객체와 관련되지는 않습니다. 그러나 어떤 클래스의 객체가 상호 작용할 필요가 있는지 찾아내는 작업이 설계에서 필요합니다.
예를 들어 은행 시스템에서 Customer라는 객체와 Account라는 객체는 연관을 맺어주어야 어떤 고객이 어떤 계좌를 개설하고 소유하고 있는지 알 수 있습니다. 송금은 계좌들 사이의 관계입니다. 또한 학사업무 시스템에서 Faculty와 Course라는 클래스, Student와 Course라는 클래스도 연관이 있습니다. 대학에서 교수는 강좌를 가르치고 학생은 강좌에 등록되어 있는 관계를 나타낸 것입니다.
위 이미지의 왼쪽 표는 Customer이 Account를 소유하는 관계를 나타낸 것이며 오른쪽 표는 Student, Course, Professor 세 클래스가 관련된 연관을 나타낸 것입니다. Student는 Course에 등록된 관계에 있고 Professor Course를 가르치는 관계에 있습니다.
객체가 다른 객체의 서비스를 사용한다면 두 객체 사이에 연관이 있다고 볼 수 있습니다. 즉 연관은 어떤 객체에서 다른 객체로 메시지가 흘러간다는 것을 의미합니다.
연관과 함께 따라오는 것이 객체의 가시성(visibility)입니다. 가시성이란 객 체의 접근 가능성을 뜻하는 것으로 A 객체와 B 객체가 연관이 있다면 A에서 B 객체를 알고 있고 접근 가능해야 합니다.
연관을 맺은 두 객체가 서로를 알게 하고 접근하게 하는 방법은 여러 가지가 있습니다.
- 연관된 객체(Course)를 전역으로 선언하여 클라이언트 객체(Student)가 접근할 수 있게 하는 방법. 이 경우 연관된 객체가 모든 다른 객체에서 오픈 된다. 즉 이 방법은 정보 은닉이라는 측면에서는 바람직한 방법은 아니다.
- 연관된 객체(Course)를 클라이언트 객체(Student)의 메시지 호출 오퍼레이션의 매개변수로 만드는 방법. 즉 연관 객체가 메소드의 매개변수가 되면 그 객체는 어딘가에 있는데 메소드를 통하여 이를 접근할 수 있다.
- 연관된 객체(Course)를 클라이언트 객체(Student)의 일부로 만드는 방법. 즉 연관된 객체가 클라이언트 객체 선언 안에 데이터 멤버로 정의된다. 이렇게 되면 클라이언트 객체가 소멸하면 연관된 객체도 소멸하는 공동 운명체가 된다. 결국 연관된 객체와 클라이언트 객체가 서로를 공유하고 가시화 하려는 것이다.
- 연관된 객체(Course)를 클라이언트 객체(Student)에서 선언하는 방법. 즉 클라이언트 객체가 연관된 객체의 포인터를 갖도록 선언한다. 이 경우 연관된 객체에서 클라이언트 객체로, 즉 역방향으로 찾을 필요가 있을 때 문제가 된다. 따라서 양방향의 탐색이 필요하다면 양쪽 객체에 모두 상대의 객체를 포인터로 갖게 하여야 한다.
참고자료 출처 : 새로쓴 소프트웨어 공학 (저자 : 최은만)