[오브젝트 01] 객체와 설계

초보개발·2022년 11월 29일
0

오브젝트

목록 보기
4/6

절차지향과 객체지향

수정하기 전, Theater의 enter 메서드 내에 Audience, TicketSeller로 부터 Bag, TicketOffice를 가져와 관람객을 입장시키는 절차를 구현함

  • Theater의 enter 메서드는 프로세스
  • Audience, TicketSeller, Bag, TicketOffice는 데이터

이처럼 프로세스와 데이터를 별도의 모듈에 위치시키는 방식을 절차적 프로그래밍이라고 부름
일반적으로 절차적 프로그래밍은 우리의 직관에 위배됨

  • 우리는 관람객, 판매원이 자신의 일을 스스로 처리할 것이라고 예상함
  • BUT, 절차적 프로그래밍에서는 관람객, 판매원 모두 수동적인 존재임

절차적 프로그래밍은 예상을 쉽게 벗어나기에 코드를 읽는 사람과 원활한 의사소통이 불가능

더 큰 문제는 절차적 프로그래밍에서는 데이터의 변경으로 인한 영향을 지역적으로 고립시키기 어려움

  • Audience, TicketSeller의 내부 구현을 변경하려면 Theater의 enter 메서드를 함께 변경해야 함
  • 변경은 버그를 양산하고 버그에 대한 두려움은 코드를 변경하기 어렵게 만듦

따라서 절차적 프로그래밍은 변경하기 어려운 코드를 양산하는 경향이 있음

변경하기 쉬운 설계는 한번에 하나의 클래스만 변경할 수 있는 설계지만 절차적 프로그래밍은 프로세스가 필요한 모든 데이터에 의존해야 한다는 근본적인 문제점 때문에 변경에 취약할 수 밖에 없음

해결 방법: 자신의 데이터를 스스로 처리하도록 프로세스의 적절한 단계를 Audience, TicketSeller로 이동

이처럼 데이터와 프로세스가 동일한 모듈 내부에 위치하도록 프로그래밍하는 방식을 객체지향 프로그래밍이라고 함
객체지향 설계의 핵심은 캡슐화를 이용해 의존성을 적절히 관리함으로써 객체 사이의 결합도를 낮추는 것

책임의 이동

객체지향과 절차지향 방식의 근본적인 차이를 만드는 것은 책임의 이동(shift of resposiblity)임

  • 책임: 기능을 가리키는 객체지향 세계의 용어

두 방식의 차이를 쉽게 이해할 수 있는 방법: 기능을 처리하는 방법을 살펴보기

  • 절차적 프로그래밍
    전체적인 작업의 흐름이 주로 Theater에 의해 제어되고 즉, 책임이 Theater에 집중되어 있음

  • 객체지향 프로그래밍
    각 객체가 자신이 맡은 일을 스스로 처리 -> 하나의 기능을 완성하는데 필요한 책임이 여러 객체에 분산

Theater에 몰려있던 책임이 각 객체로 이동한 것을 책임의 이동이라고 함

객체지향 설계에서는 독재자가 없고 각 객체가 스스로 책임지는 구조임

  • 스스로 책임을 수행하는 자율적인 객체들의 공동체를 구성함으로써 완성됨

객체와 객체는 협력하면서 특정한 역할을 수행하는데 필요하고 적절한 책임을 수행해야 함

  • 객체가 어떤 데이터를 갖는 것 보다는 객체에 어떤 책임을 할당할 것이냐에 초점을 두어야 함

설계를 어렵게 만드는 것 - 의존성
해결 방법: 의존성을 제거함으로써 객체 사이의 결합도를 낮추는 것
불필요한 세부사항을 객체 내부로 캡슐화하여 객체의 자율성을 높이고 응집도 높은 객체들의 공동체를 만들 수 있도록 함

더 개선해보기


변경 후의 코드에서 TicketOffice와 Audience 사이에 의존성이 새롭게 추가됨
(TicketOffice가 Audience에게 직접 티켓을 판매하므로 관람객을 알고 있어야 함)

의존성의 추가는 높은 결합도를 의미하고 높은 결합도는 변경하기 어려운 설계를 의미함
TicketOffice의 자율성은 높였지만 전체 설계의 관점에서는 결합도가 상승해버림
둘다 만족시키는 방법이 잘 떠오르지 않자 개발팀은 TicketOffice의 자율성보다 Audience에 대한 결합도를 낮추는 것이 더 중요하다는 결론을 지음

객체지향 설계?

첫째, 어떤 기능을 설계하는 방법은 한가지 이상일 수 있음
둘째, 동일한 기능을 여러가지로 설계 가능하므로 결국 설계는 트레이드오프의 산물임(모든 경우를 만족시킬 설계는 만들기 어려움)
설계는 균형의 예술이고 훌륭한 설계는 적절한 트레이드오프의 결과물

현실에선 수동적인 존재였지만 객체지향 세계에서는 모든 것이 능동적이고 자율적인 존재로 바뀜
레베카 워프스브록은 이처럼 능동적이고 자율적인 존재로 소프트웨어 객체를 설계하는 원칙을 의인화라고 부름

훌륭한 객체지향 설계는 소프트웨어를 구성하는 모든 객체들이 자율적으로 행동하는 설계를 말함
그 대상이 실세계에선 수동적인 존재여도 일단 객체지향 세계로 넘어오면 모두다 생명을 가진 존재로 탈바꿈 함

설계의 필요성

설계의 정의
설계란 코드를 배치하는 것

좋은 설계: 오늘의 요구하는 기능을 온전히 수행하면서 내일의 변경을 매끄럽게 수용할 수 있는 설계

  • 변경을 수용할 수 있는 설계가 중요한 이유: 요구사항은 항상 변경되기 때문, 개발 시작 시점에서 구현에 필요한 모든 요구사항들을 수집하는 것은 어려움, 수집하더라도 중간에 바뀔 수 있음
    또한, 코드를 변경할 때 버그가 추가될 가능성이 높음.

즉, 요구사항의 변경은 코드 수정을 초래하며 코드 수정은 버그 발생 가능성을 높이며 버그 발생 가능성은 코드 수정 의지를 깎아 먹음

객체지향 설계

따라서 진짜 원하는 것은 변경에 유연하게 대응할 수 있는 코드임
객체지향 프로그래밍은 의존성을 효율적으로 통제할 수 있는 다양한 방법을 제공함으로써 요구사항 변경에 좀더 수월하게 대응할 수 있는 가능성을 보여줌

변경 가능한 코드 = 이해하기 쉬운 코드

객체지향 패러다임은 내가 세상을 바라보는 방식대로 코드를 작성할 수 있도록 도움

  • 객체지향은 세상에 대해 예상하는 방식대로 객체가 행동한다는 것을 보장함으로써 코드를 좀 더 쉽게 이해할 수 있게됨

애플리케이션의 기능 구현을 위해 객체들이 협력하는 과정 속에서 객체들은 다른 객체에 의존하게 됨

  • 메시지를 전송하기 위한 이런 지식이 두 객체를 결합시키고 이 결합이 객체 간의 의존성을 만듦

훌륭한 객체지향 설계는 협력하는 객체 사이의 의존성을 적절히 관리하는 설계
객체 간의 의존성은 애플리케이션을 수정하기 어렵게 만드는 주범

0개의 댓글