Search

'객체지향프로그래밍'에 해당되는 글 4건

  1. 2021.08.29 오브젝트 리뷰 - 7
  2. 2021.08.09 오브젝트 리뷰 - 6
  3. 2021.07.25 오브젝트 리뷰 - 4
  4. 2021.07.11 오브젝트 리뷰 - 1

오브젝트 리뷰 - 7

카테고리 없음 2021. 8. 29. 13:34 Posted by 아는 개발자

다형성

 

다형성 

 

강제다형성은 언어가 지원하는 자동적인 타입 변환이나 사용자가 직접 구현한 타입 변환을 이용해 동일한 연산자를 다양한 타입에 사용할 수 있는 방식을 가리킨다.

 

매개변수 다형성은 제너릭 프로그래밍과 관련이 높은데 클래스의 인스턴스 변수나 메서드의 매개변수 타입을 임의의 타입으로 선언한 후 사용 시점에 구체적인 타입으로 지정하는 방식을 가리킨다. 

 

포함 다형성은 메시지가 동일하더라도 수신한 객체의 타입에 따라 실제로 수행되는 행동이 달라지는 능력을 말한다. 객체지향 프로그래밍에서 가장 널리 알려진 형태의 다형성이다. 포함다형성을 위한 전제 조건은 자식 클래스가 부모 클래스의 서브타입이어야 한다는 것이다. 상속의 진정한 목적은 코드 재사용이 아니라 닿령성을 위한 서브타입 계층을 구축하는 것이다

 

상속의 양면성 

 

상속의 목적은 코드 재사용이 아니라 프로그램을 구성하는 개념들을 기반으로 다형성을 가능하게 하는 타입 계층을 구축하기 위한 것이다. 타입 계층에 대한 고민 없이 코드를 재사용하기 위해 상속을 사용하면 이해하기 어렵고 유지보수하기 버거운 코드가 만들어질 확률이 높다. 

 

자식 클래스 안에 상속받은 메서드와 동일한 시그니처의 메서드를 재정의해서 부모 클래스의 구현을 새로운 구현으로 대체하는 것을 메서드 오버라이딩이라고 하고 부모 클래스에서 정의한 메서드와 이름은 동일하지만 시그니처는 다른 메서드를 자식 클래스에 추가하는 것을 메서드 오버로딩이라고 부른다. 

 

업캐스팅과 동적 바인딩 

 

부모 클래스 타입으로 선언된 변수에 자식 클래스의 인스턴스를 할당하는 것이 가능하다. 이를 업캐스팅이라고 한다. 

 

선언된 변수 타입이 아니라 메시지를 수신하는 객체의 타입에 따라 실행되는 메서드가 결정된다. 객체지향 시스템이 메시지를 처리할 적절한 메서드를 컴파일 시점이 아니라 실행 시점에 결정하기 때문이다. 이를 동적 바인딩이라고 한다. 

 

반대로 코드를 작성하는 시점에 호출할 코드가 결정되는 경우. 컴파일 타임에 호출할 함수를 결정하는 방식을 정적 바인딩 또는 컴파일타임 바인딩이라고 부른다. 

 

상속대 위임 

 

자신이 수신한 메시지를 다른 객체에게 동일하게 전달해서 처리를 요청하는 것을 위임(delegation)이라고 부른다. 위임은 본질적으로 자신이 정의하지 않거나 처리할 수 없는 속성 또는 메서드의 탐색 과정을 다른 객체로 이동시키기 위해 사용한다. 이를 위해 위임은 항상 현재의 실행 문맥을 가리키는 self 참조를 인자로 전달한다. 이것이 self 참조를 전달하지 않는 포워딩과 위임의 차이점이다.

 

서브클래싱과 서브타이핑

 

타입 

 

프로그래밍 언어의 관점에서 타입은 호출 가능한 오퍼레이션의 집합을 정의한다. 객체지향 프로그래밍에서 오퍼레이션은 객체가 수신할 수 있는 메시지를 의미한다. 따라서 객체의 타입이란 객체가 수신할 수 있는 메시지의 종류를 정의하는 것이다. 객체지향 프로그래밍에서 타입을 정의하는 것은 객체의 퍼블릭 인터페이스를 정의하는 것과 동일하다.

 

타입 계층 

 

타입 계층을 구성하는 두 타입 간의 관계에서 더 일반적인 타입을 슈퍼타입이라고 부르고 더 특수한 타입을 서브타입이라고 부른다. 객체지향 프로그래밍에서 객체의 타입을 결정하는 것은 퍼블릭 인터페이스다. 일반적인 타입이란 비교하려는 타입에 속한 객체들의 퍼블릭 인터페이스보다 더 일반적인 퍼블릭 인터페이스를 가지는 객체들의 타입을 의미한다. 

 

서브클래싱과 서브타이핑

 

타입 계층의 의미는 행동이라는 문맥에 따라 달라질 수 있다. 올바른 타입 계층이라는 의미 역시 문맥에 따라 달라질 수 있다. 따라서 슈퍼타입과 서브타입 관계에서는 is-a 보다 행동 호환성이 더 중요하다. 어떤 두 대상이 is-a 라고 표현할 수 있더라도 상속을 사용할 예비후보 정도로만 생각해야한다. 

 

타입의 이름 사이에 개념적으로 연관성이 있다고 하더라도 행동에 연관성이 없다면 is-a 관계를 사용하지 말아야 한다. 행동 호환 여부를 판단하는 기준은 클라이언트 관점이다. 클라이언트 관점에서 두 타입이 동일하게 행동할 것이라고 기대한다면 두 타입을 타입 계층으로 묶을 수 있다. 그렇지 않다면 두 타입을 타입 계층으로 묶어서는 안된다. 

 

서브클래싱은 다른 클래스의 코드를 재사용할 목적으로 상속을 사용하는 경우를 가리킨다. 구현상속 또는 클래스상속이라고 부른다. 서브타이핑은 타입 계층을 구성하기 위해 상속을 사용하는 경우를 가리킨다. 부모 클래스는 자식 클래스의 슈퍼타입이 되고 자식 클래스는 부모 클래스의 서브타입이 된다. 인터페이스 상속이라고 부르기도 한다.  서브타이핑과 서브클래싱을 나누는 기준은 상속을 사용하는 목적이다. 

 

서브타이핑 관계가 유지되기 위해서는 서브타입이 슈퍼타입이 하는 모든 행동을 동일하게 할 수 있어야 한다. 어떤 타입이 다른 타입의 서브타입이 되기 위해서는 행동호환성을 만족시켜야 한다. 

 

리스코프 치환 원칙 

 

올바른 상속 관계의 특징을 정의하기 위해 리스코프 치환원칙이 있다. 자식 클래스가 부모 클래스와 행동 호환성을 유지함으로써 부모 클래스를 대체할 수 있도록 구현된 상속관계만을 서브타이핑이라고 볼 수 있다. 

 

상속관계는 클라이언트 관점에서 자식 클래스가 부모 클래스를 대체할 수 있을때만 올바르다.  is-a 관계는 객체지향에서 중요한 것은 객체의 속성이 아니라 객체의 행동이라는 점을 강조한다. 

728x90

오브젝트 리뷰 - 6

기술/아키텍처 2021. 8. 9. 20:00 Posted by 아는 개발자

유연한 설계

 

개방-폐쇄 원칙 

 

개방-폐쇄 원칙은 런타임 의존성과 컴파일타임 의존성에 관한 이야기다. 개방-폐쇄 원칙을 수용하는 코드는 컴파일타임 의존성을 수정하지 않고도 런타임 의존성을 쉽게 변경할 수 있다. 개방-폐쇄 원칙의 핵심은 추상화에 의존하는 것이다. 올바른 추상화를 설계하고 추상화에 대해서만 의존하도록 관계를 제한함으로써 설계를 유연하게 확장할 수 있다.

 

생성과 사용의 분리

 

유연하고 재사용 가능한 설계를 원한다면 객체와 관련된 두 가지 책임을 서로 다른 객체로 분리해야 한다. 하나는 객체를 생성하는 것이고, 다른 하나는 객체를 사용하는 것이다. 한 마디로 말해서 객체에 대한 생성과 사용을 분리(seprating use from creation)해야 한다.

 

경우에 따라 객체 생성과 관련된 책임만 전담하는 별도의 객체를 추가하고 Client는 이 객체를 사용하도록 만들 수 있다. 이처럼 생성과 사용을 분리하기 위해 객체 생성에 특화된 객체를 FACTORY라고 부른다.

 

의존성 주입 

 

객체가 아닌 외부의 독립적인 객체가 인스턴스를 생성한 후 이를 전달해서 의존성을 해결하는 방법을 의존성 주입이라고 부른다. 의존성 주입은 의존성을 해결하기 위해 의존성을 객체의 퍼블릭 인터페이스에 명시적으로 드러내서 외부에서 필요한 런타임 의존성을 전달할 수 있도록 만드는 방법을 포괄하는 명칭이다. 

 

의존성 주입은 필요한 의존성을 클래스 퍼블릭 인터페이스에 명시적으로 드래너기 때문에 의존성을 이해하기 위해 코드 내부를 읽을 필요가 없어 객체의 캡슐을 단단하게 보호한다. 가급적 의존성을 객체의 퍼블릭 인터페이스에 노출하라. 의존성을 구현 내부에 숨기면 숨길수록 코드를 이해하기도, 수정하기도 어려워진다.

 

상속과 코드 재사용 

 

상속과 중복 코드 

 

중복코드가 가지는 가장 큰 문제는 코드를 수정하는 데 필요한 노력을 몇 배로 증가시킨다는 것이다. 중복 여부를 판단하는 기준은 변경이다. 요구사항이 변경됐을 때 두 코드를 함께 수정해야 한다면 이 코드는 중복이다. 

 

상속은 객체지향 프로그래밍에서 중복을 제거하기 위한 대표적인 방법이다. 상속을 이용해 코드를 재사용하기 위해서는 부모 클래스의 개발자가 세웠던 가정이나 추론 과정을 정확하게 이해해야한다. 이것은 자식 클래스의 작성자가 부모 클래스의 구현 방법에 대한 정확한 지식을 가져야 한다는 것을 의미한다. 따라서 상속은 결합도를 높인다. 그리고 부모 클래스와 자식 클래스 사이의 강한 결합이 코드를 수정하기 어렵게 만든다.

 

취약한 기반 클래스 문제 

 

부모클래스의 변경에 의해 자식 클래스가 영향을 받는 현상을 취약한 기반 클래스 문제라고 부른다. 취약한 기반 클래스 문제는 캡슐화를 약화시키고 결합도를 높인다. 상속은 자식 클래스가 부모 클래스의 구현 세부사항에 의존하도록 만들기 때문에 캡슐화를 약화시킨다. 객체지향의 기반은 캡슐화를 통한 변경의 통제인데 상속은 코드 재사용을 위해 캡슐화의 장점을 희석시키고 구현에 대한 결합도를 높임으로써 객체지향이 가진 강력함을 반감시킨다.

 

 

 

 

728x90

'기술 > 아키텍처' 카테고리의 다른 글

오브젝트 리뷰 - 6  (0) 2021.08.09
오브젝트 리뷰 - 5  (0) 2021.07.27
오브젝트 리뷰 - 4  (0) 2021.07.25
오브젝트 리뷰 - 3  (0) 2021.07.21
오브젝트 리뷰 - 2  (0) 2021.07.12
오브젝트 리뷰 - 1  (0) 2021.07.11

오브젝트 리뷰 - 4

기술/아키텍처 2021. 7. 25. 15:56 Posted by 아는 개발자

https://book.naver.com/bookdb/book_detail.nhn?bid=15007773

 

오브젝트

역할, 책임, 협력을 향해 객체지향적으로 프로그래밍하라!객체지향으로 향하는 첫걸음은 클래스가 아니라 객체를 바라보는 것에서부터 시작한다. 객체지향으로 향하는 두번째 걸음은 객체를

book.naver.com

 

메시지와 인터페이스 

 

협력과 메시지

 

메시지는 객체 사이의 협력을 가능하게 하는 매개체다. 객체가 다른 객체에게 접근할 수 있는 유일한 방법은 메시지를 전송하는 것뿐이다. 전통적인 방법은 클라이언트-서버 모델이다. 메시지를 전송하는 객체를 클라이언트, 메시지를 수신하는 객체를 서버라 부르며 협력은 클라이언트가 서버의 서비스를 요청하는 단방향 상호작용이다. (p176)

 

객체가 독립적으로 수행할 수 있는 것보다 더 큰 책임을 수행하기 위해서는 다른 객체와 협력해야 한다. 두 객체 사이의 협력을 가능하게 해주는 매개체가 바로 메시지다. (p177)

 

메시지는 객체들이 협력하기 위해 사용할 수 있는 유일한 의사소통 수단이다. 한 객체가 다른 객체에게 도움을 요청하는 것을 메시지 전송 또는 메시지 패싱이라고 부른다. 이때 메시지를 전송하는 객체를 메시지 전송자라고 부르고 메시지를 수신하는 객체를 메시지 수신자라고 부른다. 메시지는 오퍼레이션명과 인자로 구성되며 메시지 전송은 여기에 메시지 수신자를 추가한 것이다. (p177)

 

메시지를 수신했을 때 실제로 실행되는 함수 또는 프로시저를 메서드라 부른다. 코드 상에서 동일한 이름의 변수에게 동일한 메시지를 전송하더라도 객체의 타입에 따라 실행되는 메서드가 달라질 수 있다. 객체는 메시지와 메서드라는 두 가지 서로 다른 개념을 실행 시점에 연결해야 하기 때문에 컴파일 시점과 실행 시점의 의미가 달라질 수 있다. 이런 메시지와 메서드의 구분은 전송자와 메시지 수신자가 느슨하게 결합될 수 있게 한다. (p178)

 

객체가 의사소통을 위해 외부에 공개하는 메시지의 집합을 퍼블릭 인터페이스라고 부른다. 프로그래밍 언어 관점에서 퍼블릭 인터페이스에 포함된 메시지를 오퍼레이션이라고 부른다. 그에 비해 메시지를 수신했을 때 실제로 실행되는 코드는 메서드라고 부른다. (p179)

 

오페레이션의 이름과 파라미터 목록을 합쳐 시그니처라고 부른다. 오퍼레이션은 실행 코드 없이 시그니처만을 정의한 것이고 메서드는 이 시그니처에 구현을 더한 것이다. (p180)

 

인터페이스와 설계 품질 

 

좋은 인터페이스는 최소한의 인터페이스와 추상적인 인터페이스라는 조건을 만족해야한다 (p181)

 

디미터 법칙은 객체 내부 구조에 강하게 결합되지 않도록 협력 경로를 제한한다. 오직 하나의 도트만 사용하라는 말로 요약되기도 한다. 디미터 법칙을 따르기 위해서는 클래스가 특정한 조건을 만족하는 대상에게만 메시지를 전송하도록 프로그래밍 해야한다. 디미터 법칙을 따르면 부끄럼타는 코드를 작성할 수 있다. 부끄럼타는 코드란 불필요한 어떤 것도 다른 객체에게 보여주지 않으며 다른 객체의 구현에 의존하지 않는 코드를 의미한다. (p183, 184, 185)

 

디미터 법칙을 만족하지 않은 경우 내부 구조에 대해 물어보고 반환받은 요소에 대해 연쇄적으로 메세지를 전송하는 경우가 생기는데 이런 경우를 기차 충돌(train wreck)이라 한다. 기차 충돌은 클래스의 내부 구현이 외부로 노출됐을 때 나타나는 전형적인 형태다. (p186)

 

훌륭한 메시지는 객체의 상태에 관해 묻지 말고 원하는 것을 시켜야한다. 묻지 말고 시켜라는 이런 스타일의 메시지 작성을 장려하는 원칙이다. 객체의 정보를 이용하는 행동을 객체의 외부가 아닌 내부에 위치시키기 때문에 자연스럽게 정보와 행동을 동일한 클래스 안에 두게 되고 자연스럽게 정보 전문가에게 책임을 할당하게 되고 높은 응집도를 가진 클래스를 얻게 된다 (p186, 187)

 

메서드 이름을 짓는 두번째 방법은 '어떻게'가 아니라 '무엇'을 하는지를 드러내는 것이다. 무엇을 하는지를 드러내는 이름은 코드를 이해하기 쉽고 유연한 코드를 낳는 지름길이다. 무엇을 하는지 드러내도록 메서드의 이름을 짓기 위해서는 객체가 협력 안에서 수행해야 하는 책임에 관해 고민해야한다. 이처럼 무엇을 하느냐에 따라 메서드의 이름을 짓는 패턴을 의도를 드러내는 선택자라고 부른다. (p188, 189, 190)

 

명령 - 쿼리 분리 원칙 

 

어떤 절차를 묶어 호출하도록 이름을 부여한 기능 모듈을 루틴이라 부른다. 루틴은 프로시저와 함수로 구분 되는데 프로시저는 정해진 절차에 따라 내부 상태를 변경하는 루틴이며 함수는 어떤 절차에 따라 필요한 값을 계산해서 반환하는 루틴의 종류이다. 명령은 객체의 인터페이스 측면에서 프로시저에 해당하고, 쿼리는 함수에 해당한다. (p202)

 

명령-쿼리 분리 원칙의 요지는 오퍼레이션은 부수효과를 발생시키는 명령이거나 부수효과를 발생시키지 않는 쿼리 중 하나여야 한다는 것이다. 어떤 오퍼레이션도 명령인 동시에 쿼리여서는 안된다. 명령은 상태를 변경할 수 있지만 상태를 반환해서는 안되며 쿼리는 객체의 상태를 반환할 수 있지만 상태를 변경해서는 안된다. (p203)

 

명령-쿼리 분리 원칙은 부수효과를 가지는 명령으로부터 부수효과를 가지지 않는 쿼리를 명백하게 분리함으로써 제한적이나마 참조 투명성의 혜택을 누릴 수 있게 해준다 (p213)

 

객체 분해

 

프로시저 추상화와 데이터 추상화 

 

현대적인 프로그래밍 언어를 특징 짓는 중요한 두 가지 추상화 메커니즘은 프로시저 추상화와 데이터 추상화다. 프로시저 추상화는 소프트웨어가 무엇을 해야하는지를 추상화하고 테이터 추상화는 소프트웨어가 무엇을 알아야 하는지를 추상화한다. (p218)

 

프로시저 추상화를 중심으로 시스템을 분해하기로 결정했다면 기능분해(functional decomposition)의 길로 들어서는 것이다. 기능 분해는 알고리즘 분해라고 부르기도 한다. 데이터 추상화를 중심으로 시스템을 분해하기로 결정했다면 데이터를 중심으로 타입을 추상화(type abstraction)하는 방향과 데이터를 중심으로 프로시저를 추상화 하는 방법(procedure abstraction)중 하나를 선택한다 (p218)

 

프로시저 추상화와 기능 분해

 

전통적인 기능 분해 방법은 하향식 접근법을 따른다. 하향식 접근법이란 시스템을 구성하는 가장 최상위 기능을 정의하고 좀 더 작은 단계의 하위 기능으로 분해해가는 방법을 말한다. (p219)

 

하향식 접근법과 기능분해는 근본적으로 변경에 취약한 설계를 갖는다. 메인 함수를 유일한 정상으로 간주하는 하향식 기능 분해의 경우에는 새로운 기능을 추가할 때마다 매번 메인 함수를 수정해야 한다. (p226, 227)

 

하향식 접근법은 비즈니스 로직을 설계하는 초기 단계부터 입력방법과 출력 양식을 함께 고민하도록 강요한다. 그러나 사용자 인터페이스는 시스템 내에서 가장 많은 변경이 발생하는 부분이므로 수정이 발생하면 상대적으로 변경이 적은 비즈니스 로직까지 영향을 미치게 된다. 근본적으로 변경에 불안정한 아키텍처가 만들어진다. (p229)

 

하향식 접근법의 경우 처음부터 구현을 염두에두기 때문에 자연스럽게 함수들의 실행 순서를 정의하는 시간 제약을 강조한다. 분해를 진행할 수 없어 기능 분해 방식은 중앙집중 제어스타일의 형태를 띨 수 밖에 없다. 이를 해결하기 위해선 시간 제약에 대한 미련을 버리고 좀 더 안정적인 논리적 제약을 설계 기준으로 삼아야 한다. 객체 지향은 삼수 간의 호출 순서가 아니라 객체 사이의 논리적인 관계를 중심으로 설계를 이끌어간다. (p230)

 

모듈 

 

시스템을 모듈 단위로 분해하기 위한 기본 원리로 시스템에서 자주 변경되는 부분을 상대적으로 덜 변경되는 안정적인 인터페이스 뒤로 감춰야 한다는 것이 핵심이다. 모듈 분해는 감춰야 하는 비밀을 선택하고 비밀 주변에 안정적인 보호막을 설치하는 보존의 과정이다. 비밀을 결정하고 모듈을 분해한 후에는 기능 분해를 이용해 모듈에 필요한 퍼블릭 인터페이스를 구현할 수 있다. 모듈은 복잡성과 변경 가능성을 감춰야한다. (p235, 236)

 

모듈은 기능이 아니라 변경의 정도에 따라 시스템을 분해한다. 각 모듈은 외부에 감춰야 하는 비밀과 관련성 높은 데이터와 함수의 집합이다. 따라서 모듈 내부는 높은 응집도를 유지한다. 또한 퍼블릭 인터페이스를 통해서만 통신해야 하므로 낮은 결합도를 유지한다. 모듈에게 있어 핵심은 데이터다. (p239)

 

클래스 

 

명확한 의미에서 클래스는 추상 데이터 타입과는 다르다. 핵심적인 차이는 클래스는 상속과 다형성을 지원하는데 비해 추상 데이터 타입은 지원하지 못한다는 것이다.  타입 추상화를 기반으로 하는 대표적인 기법이 바로 추상 데이터 타입이다. 추상 데이터 타입은 오퍼레이션을 기준으로 여러가지 타입을 나타낼 수 있다. 반면 객체 지향은 타입을 기준으로 오퍼레이션을 묵는다. (p245, 246)

 

실제 내부에서 수행되는 절차는 다르지만 클래스를 이용한 다형성은 절차에 대한 차이점을 감춘다. 다시 말해 객체 지향은 절차 추상화다.

 

 

 

 

 

728x90

'기술 > 아키텍처' 카테고리의 다른 글

오브젝트 리뷰 - 6  (0) 2021.08.09
오브젝트 리뷰 - 5  (0) 2021.07.27
오브젝트 리뷰 - 4  (0) 2021.07.25
오브젝트 리뷰 - 3  (0) 2021.07.21
오브젝트 리뷰 - 2  (0) 2021.07.12
오브젝트 리뷰 - 1  (0) 2021.07.11

오브젝트 리뷰 - 1

기술/아키텍처 2021. 7. 11. 15:53 Posted by 아는 개발자

https://book.naver.com/bookdb/book_detail.nhn?bid=15007773

 

오브젝트

역할, 책임, 협력을 향해 객체지향적으로 프로그래밍하라!객체지향으로 향하는 첫걸음은 클래스가 아니라 객체를 바라보는 것에서부터 시작한다. 객체지향으로 향하는 두번째 걸음은 객체를

book.naver.com

 

객체지향 프로그래밍을 다룬 오브젝트를 읽으며 나의 잘못된 과거의 코딩이 생각나던 구절, 나도 모르게 밑줄을 치게 되던 주옥같은 문장, 기억해야할 용어를 정리해본다. 이 책의 모든 내용을 한 포스트에 정리하긴 어려울 것 같고 공부한 날짜별로 메모하고 싶은 내용만 담아본다. 기본적으로 책의 내용을 참조 했지만 공부한 내용을 요약해서 정리하고자 몇몇 문장과 단어를 추가하고 수정했다. 그리고 페이지 별로 주요 문장을 뽑아냈기 때문에 목차별로 전달하고자 하는 핵심 메시지가 누락돼 저자의 의도가 제대로 전달되지 않을 수 있다. 추상적이거나 애매해보이는 보이는 표현은 책을 통해서 확인 바란다.

 

캡슐화의 개념과 목적

 

- 개념적이나 물리적으로 객체 내부의 세부적인 사항을 감추는 것. 목적은 변경하기 쉬운 객체로 만드는 것이며, 캡슐화를 통해 객체 내부 접근을 제한하면 객체와 객체 사이의 결합도를 낮아지기 때문에 변경하기 쉬운 객체로 만드는게 가능하다. (p20)

 

응집도가 높은 객체란

 

- 밀접하게 연관된 작업만을 수행하고, 연관성 없는 작업은 다른 객체에게 위임하는 객체. 스스로 자신의 데이터에 책임을 지는 객체가 응집도가 높다고 말할 수 있다. (p26)

 

절차지향 프로그래밍과 객체지향 프로그래밍

 

- 프로세스와 데이터를 별도의 모듈에 위치시키는 방식을 절차적 프로그래밍(Procedural Programming)이라 부르며 반대로 데이터와 프로세스가 동일한 모듈 내부에 위치하도록 프로그래밍 하는 방식을 객체지향 프로그래밍(Object-Oriented Programming)이라 한다. (p26) 여기서 프로세스는 처리하는 작업을 담당하는 메서드에 해당하고 데이터는 작업을 처리할 때 필요한 정보를 말한다. 

 

- 절차지향 프로그래밍에서는 별도의 모듈에 프로세스와 데이터가 있기 때문에 의존관계가 높아진다. 반명 객체지향 프로그래밍에서는 연관관계가 있는 프로세스와 데이터가 하나의 모듈에 있기 대문에 의존관계가 낮아진다.

 

훌륭한 객체 지향 설계를 위한 원칙

 

- 캡슐화를 이용해 의존성을 적절히 관리함으로써 객체 사이의 결합도를 낮춘다 (p27)

- 객체지향 설계에서는 독재자가 존재하지 않고 각 객체에 책임이 적절하게 분배된다. 따라서 각 객체는 자신을 스스로 책임진다. (p28)

- 소프트웨어를 구성하는 모든 객체들이 자율적으로 행동하는 설계 (p34)

- 변경이 쉬우며 협력하는 객체 사이의 의존성을 적절하게 관리 (p36)

 

도메인 

 

- 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야를 도메인이라 부른다 (p41)

 

- 어떤 클래스가 필요한지를 고민하기 전에 어떤 객체들이 필요한지를 고민한다. 어떤 객체들이 어떤 상태와 행동을 가지는지 우선 결정한다. 그리고 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 일원으로 봐야한다. (p41) 

 

자율적인 객체 

 

- 객체는 상태와 행동을 가지는 복합적인 존재이며 스스로 판단하고 행동하는 자율적인 존재.  (p44)

- 객체 내부에 대한 접근을 통제해 객체를 자율적인 존재로 만든다. 자율적으로 만드는 것은 외부의 의존성으로부터 자유로워지는 것을 의미한다. (p44) 

- 외부에서 접근가능한 부분을 퍼블릭 인터페이스(public interface)라고 하며 내부에서만 접근 가능한 부분을 구현(implementation)이라 부른다. (p44)

 

객체 간의 협력 

 

- 다른 객체의 인터페이스에 공개된 행동을 수행하도록 요청(Request) 할 수 있고 요청 받은 객체는 자율적인 방법에 따라 응답(Response)한다. (p49)

- 객체끼리 상호작용할 수 있는 유일한 방법은 메시지를 전송하는 것 뿐이다. 다른 객체에게 요청이 도착할 때 해당 객체가 메시지를 수신했다고 이야기한다. 수신된 메시지를 처리하기 위한 자신만의 방법을 메서드라고 한다 (p49)

 

상속과 다형성 

 

- 상속과 인터페이스를 사용하면 컴파일타임 의존성과 실행 시점의 의존성이 다를 수 있다. 클래스 사이의 의존성과 객체사이의 의존성이 동일하지 않을 수 있다. (p59)

- 상속과 인터페이스를 사용하면 코드가 유연해진다. 그러나 유연해진만큼 코드를 이해하고 디버깅하는 것은 어려워진다. 반대로 유연성을 억제하면 재사용과 확장가능성은 낮아진다 (p59) 

- 동일한 메시지를 전송하지만 실행되는 메서드는 수신되는 객체에 따라서 달라진다. 이를 다형성이라 부른다. 다형성은 컴파일 시간 의존성과 실행시간 의존성을 다를수 있는 사실을 기반으로 하며 동일한 메시지를 수신했을 때 객체의 타입에 따라 다르게 응답하는 능력을 말한다. (p 63)

 

728x90

'기술 > 아키텍처' 카테고리의 다른 글

오브젝트 리뷰 - 3  (0) 2021.07.21
오브젝트 리뷰 - 2  (0) 2021.07.12
오브젝트 리뷰 - 1  (0) 2021.07.11
응집도(Cohesion)와 결합도(Coupling)  (0) 2021.07.10
클린 아키텍처  (0) 2021.05.20
DIP(Dependency Inversion Principle)  (0) 2021.05.09