클래스를 이용한 타입 계층 구현 타입은 객체의 퍼블릭 인터페이스를 가리킨다. 클래스는 객체의 타입과 구현을 동시에 정의하는 것과 같다고 볼 수 있다. 이러한 점이 객체지향 언어에서 클래스를 사용자 정의 타입(user-defined data type)이라고 부르는 이유다. public class Phone { private Money amount; private Duration seconds; private List calls = new ArrayList(); public Phone(Money amount, Duration seconds) { this.amount = amount; this.seconds = seconds; } public Money calculateFee() { // 생략 } } Phon..
단순히 코드를 재사용할 목적으로 상속을 사용해서는 안된다. 재사용을 위해 상속을 사용할 경우 부모 클래스와 자식 클래스가 강하게 결합된다. 상속을 사용하는 일차적인 목표는 코드 재사용이 아니라 타입 계층을 구현하는 것이어야 한다. 코드 재사용은 상속이 아닌 합성을 사용하는 게 올바르다. 💡 객체지향 프로그래밍과 객체 기반 프로그래밍 객체 기반 프로그래밍이란 상태와 행동을 캡슐화한 객체를 조합해서 프로그램을 구성하는 방식을 가리킨다. 이 정의에 따르면 객체지향 프로그래밍 역시 객체 기반 프로그래밍의 한 종류다. 단 객체 기반 프로그래밍은 상속과 다형성을 지원하지 않는다. 타입 먼저, 프로그래밍 언어 관점에서의 타입과 개념 관점에서의 타입에 대해 알아보자. 개념 관점의 타입 개념 관점에서 타입은 우리가 인지..
상속의 단점을 피하면서 코드를 재사용하기 위해 합성을 사용할 수 있다. 합성은 구현에 의존하지 않고, 퍼블릭 인터페이스에 의존한다. 상속은 부모 클래스에 구현된 코드를 재사용하지만, 합성은 포함된 객체의 퍼블릭 인터페이스를 재사용한다. 이는 구현에 대한 의존성을 인터페이스에 대한 의존성으로 변경시키고, 클래스 사이의 결합도를 낮추는 효과를 준다. 상속을 합성으로 변경하기 10장에서 코드 재사용을 위해 상속을 남용했을 때 생길 수 있는 문제로 3가지 예시를 알아봤었다. 불필요한 인터페이스 상속 문제 메서드 오버라이딩의 오작용 문제 부모 클래스와 자식 클래스의 동시 수정 문제 상속 관계를 합성으로 바꿔서 이 세 가지 문제를 해결할 수 있다. 불필요한 인터페이스 상속 문제 java.util.Properties..
이번 장에서는 클래스를 재사용하기 위해 새로운 클래스를 추가하는 가장 대표적인 기법인 상속과 합성 중 상속과 잘못된 상속으로 인해 발생하는 문제들과 해결방안에 대해 알아보겠습니다. 상속과 중복 코드 DRY원칙 중복 코드는 변경을 방해한다. 중복 코드가 가지는 가장 큰 문제는 코드를 수정하는 데 필요한 노력을 몇 배로 증가시킨다는 것이다. 중복 코드는 수정과 테스트에 드는 비용을 증가시킨다. 만약 요구사항이 변경됐을 때 두 코드를 함께 수정해야 한다면 이 코드는 중복이다. 함께 수정할 필요가 없다면 중복이 아니다. 모양이 유사하다는 것은 단지 중복의 징후일 뿐이다. **DRY는 “반복하지 마라”**라는 뜻의 Don’t Repeat Yourself의 첫 글자를 모아 만든 용어로 간단히 말해 동일한 지식을 중..
개방-폐쇄 원칙 소프트웨어 개체(클래스, 모듈, 함수 등등)는 확장에 대해 여려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다. 확장에 대해 열려 있다 : 애플리케이션의 요구사항이 변경될 때 이 변경에 맞게 새로운 ‘동작’을 추가해서 애플리케이션의 기능을 확장할 수 있다. 수정에 대해 닫혀 있다 : 기존의 ‘코드’를 수정하지 않고도 애플리케이션의 동작을 추가하거나 변경할 수 있다. 컴파일 타임의 의존성을 고정시키고 런타임 의존성을 변경하라 의존성 관점에서 개방-폐쇄 원칙을 따르는 설계란 컴파일 타임 의존성은 유지하면서 런타임 의존성의 가능성을 확장하고 수정할 수 있는 구조라고 할 수 있다. 런타임 의존성 : 실행 시에 협력에 참여하는 객체들 사이의 관계 컴파일 타임 의존성 : 코드에서 드러나는 클래스들..
이번 주 스터디는 8, 9장에 대해 나눈다. 7장은 쉬어가는 파트라고 해서 건너뛰었다. 8장에서는 의존성을 잘 관리하기 위해 의존성을 이해하고 의존성을 관리하는 원칙과 기법에 관해 학습한다. 의존성 이해하기 변경과 의존성 어떤 객체가 협력하기 위해 다른 객체를 필요로 할 때, 두 객체 사이에서는 의존성이 존재하게 된다. 의존성은 실행 시점과 구현 시점에 따라 다른 의미를 가진다. 실행 시점 : 의존하는 객체가 정상적으로 동작하기 위해서는 실행 시에 의존 대상 객체가 반드시 존재해야 한다. 구현 시점 : 의존 대상 객체가 변경될 경우 의존하는 객체도 함께 변경된다. public class PeriodCondition impolements DiscountCondition { public boolean isS..
이번 장에서는 협력과 메시지에 관련한 용어를 정리하고, 인터페이스 설계를 위한 원칙, 기법들에 대해서 소개한다. 도움 되는 내용들이 많이 있었다. 협력과 메시지 협력은 어떤 객체가 다른 객체에게 무언가를 요청할 때 시작된다. 메시지는 협력을 가능하게 하는 매개체이다. 객체는 메시지를 전송하고, 메시지를 수신한 객체는 이를 처리하고 응답한다. 클라이언트 - 서버 모델 두 객체 사이의 협력관계는 클라이언트 - 서버 모델로 자주 비유한다. 클라이언트 : 메시지를 전송하는 객체 서버 : 메시지를 수신하는 객체 그러나 실제로 객체는 협력의 관점에서 두 가지 종류의 메시지 집합으로 구성된다. 객체가 수신하는 메시지의 집합과 외부의 객체에게 전송하는 메시지의 집합이다. 메시지와 메시지 전송 한 객체가 다른 객체에게 ..
이번 글은 같이 스터디를 진행한 친구의 글을 옮긴 것이다. 원글은 여기에서 볼 수 있다. 올바른 책임 할당을 위한 GRASP패턴 GRASP패턴은 “General Responsibility Assignment Softwarre Pattern(일반적인 책임 할당을 위한 소프트웨어 패턴)”의 약자로 객체에게 책임을 할당할 때 지침으로 삼을 수 있는 원칙들의 집합을 패턴 형식으로 정리한 것이다. 1. 도메인 개념에서 출발하기 설계를 시작하기 전에 도메인에 대한 개략적인 모습을 그려 보는 것이 유용 도메인 개념이란 책임 할당의 대상으로 사용하는 거대한 틀 설계를 시작하는 단계에서는 개념들의 의미와 관계가 정확하거나 완벽할 필요가 없다. 중요한 것은 완벽한 설계가 아닌 설계를 시작하는 것! 2. 정보 전문가(INF..