모델
,패턴
,전형 적인 예
를 의미하는 그리스어인파라데이그마
에서 유래- 50년이 지난 현대에서는
한 시대의 사회 전체가 공유 하는 이론이나 방법, 문제 의식 등의 체계
를 의미
과학은
단순한 계단식 발전의 형태
가 아닌새로운 발견이 기존의 과학적 견해를 붕괴
시키는 혁명적인 과정을 거쳐 발전
과거의 패러다임이 새로운 패러다임에 의해 대체
됨으로써 정상과학의 방향과 성격이 변하는 것
을 의미절차형 패러다임에서 객체지향 패러다임으로의 변화를 의미
특정 시대의 어느
성숙한 개발자 공동체
에 의해 수용된프로그래밍 방법과 문제 해결 방법, 프로그래밍 스타일
프로그래밍 패러다임
은 과거에 있던 패러다임의 형태를 보완하여 만들어지는 발전적 패러다임
개발자 공동체
가동일한 프로그래밍 스타일과 모델을 공유
할 수 있게 하므로써불 필요한 부분에 대한 의견 충돌을 방지
2.
객체 지향 패러다임
이 제시하는프로그래밍 패러다임을 설명
- 이렇게 함으로써 코드 개발 시
객체 지향 패러다임을 생각하여 개발
하며동일한 규칙과 표준에 따라 프로그램을 작성
실무가 어느 정도 발전
하고 난 다음에야 비로소 실무의 실용성을 입증할 수 있는이론이 서서히 그 모습을 갖춰가기 시작
하고,해당 분야가 충분히 성숙해지는 시점
에 이르러서야이론이 실무를 추월
하게 된다. - 로버트 L. 글래스 -
- 실무에서는 다양한 규모의 SW를 성공적으로 유지보수 하고 있음
- 하지만 소프트웨어 유지보수와 관련된 효과적인 이론이 발표된 적은 없음
- 그렇기에
소프트웨어 설계와 유지보수의 중점
을 두려면이론이 아닌 실무에 초점
을 맞추는 것이 효과적
- 소극장은 먼저
관람객 가방 안에 초대장이 있는지 확인
초대장이 있다면
이벤트에 당첨된 관람객이기에판매원에게 받은 티켓을 관람객 가방 안에 추가
초대장이 없다면
티켓을 판매
해야 함
- 소극장은
관람객의 가방에서 티켓 금액만큼을 차감
한 후매표소 금액 증가
- 소극장은
관람객의 가방 안에 티켓을 넣어 줌
으로써관람객의 입장절차 끝냄
Theater
public class Theater {
private TicketSeller ticketSeller;
public Theater(TicketSeller ticketSeller) {
this.ticketSeller = ticketSeller;
}
public void enter(Audience audience) {
if(audience.getBag().hasInvitation()) {
Ticket ticket = ticketSeller.getTicketOffice().getTicket();
audience.getBag().setTicket(ticket);
} else {
Ticket ticket = ticketSeller.getTicketOffice().getTicket();
audience.getBag().minusAmount(ticket.getFee());
ticketSeller.getTicketOffice().plusAmount(ticket.getFee());
audience.getBag().setTicket(ticket);
}
}
}
- 실행 중에
제대로 동작
변경
을 위해 존재
코드를 읽는 사람과 의사소통
하는 것
제대로 동작하는 것은 만족
하지만, 변경에 용이하지 않으며, 코드를 읽는 사람과 의사소통하기 어려운 코드
라는 것다시 한번 enter 메서드가 수행하는 일
을 살펴보자.
- 소극장은 먼저
관람객 가방 안에 초대장이 있는지 확인
초대장이 있다면
이벤트에 당첨된 관람객이기에판매원에게 받은 티켓을 관람객 가방 안에 추가
초대장이 없다면
티켓을 판매
해야 함- 소극장은
관람객의 가방에서 티켓 금액만큼을 차감
한 후매표소 금액 증가
- 소극장은
관람객의 가방 안에 티켓을 넣어 줌
으로써관람객의 입장절차 끝냄
관람객과 판매원
이 소극장의 통제를 받는 수동적인 존재
라는 것
판매원
은 매표소 안에 가만히 앉아서 티켓 수량만 확인
하는 존재가방만 들고 가며 아무 일도 하지 않음
이해 가능한 코드
는 우리의 예상에서 크게 벗어나지 않아야 하는 것
인데, 각 객체의 하는 일
이 우리가 생각하고 있는 것과 다른 범위에서 동작
하고 있다는 것
가장 심각한 문제 는
Audience와 TicketSeller를 변경
하는 경우Theater도 함께 변경
해야하는 사실
만약 관람객이 가방이 아닌 신용 카드나 현금만 들고 다닌다면
Audience 클래스에서 Bag를 제거
할 뿐 아니라, Theater의 enter 메서드도 수정
해야 함
이것은 객체 사이의 의존성
과 관련된 문제
의존성
은 변경에 대한 영향
을 암시어떤 객체가 변경
되면 그 객체에게 의존하는 다른 객체도 함께 변경
될 수 있다는 사실객체 사이의 의존성이 과한 경우
를 결합도가 높다
고 말함
객체 지향 설계의 목표
는 애플리케이션의기능을 구현
하는데 필요한최소한의 의존만 유지
하며불필요한 의존성을 제거
하며객체 사이의 결합도를 낮춰
변경이 용이한 설계
를 만드는 것이다.
각 객체
에 대해서본인의 일은 본인이 하도록 규정
하는 것
Theater는
관람객이 소극장에 입장
하도록 하는 것
Audience
는 스스로 가방 안의 현금과 초대장을 처리
하는 것
TicketSeller
는 스스로 매표소의 티켓과 판매 요금을 다루는 것
TicketSeller가 직접 TicketOffice 처리
public class TicketSeller {
private TicketOffice ticketOffice;
public TicketSeller(TicketOffice ticketOffice) {
this.ticketOffice = ticketOffice;
}
public void toSell(Audience audience) {
if(audience.getBag().hasInvitation()) {
Ticket ticket = ticketOffice.getTicket();
audience.getBag().setTicket(ticket);
} else {
Ticket ticket = ticketOffice.getTicket();
audience.getBag().minusAmount(ticket.getFee());
ticketOffice.plusAmount(ticket.getFee());
audience.getBag().setTicket(ticket);
}
}
}
enter 메서드에 있는 로직
을 TicketSeller 클래스의 toSell 메서드로 새로 생성
함으로써 자신의 일을 직접 처리public class Theater {
private TicketSeller ticketSeller;
public Theater(TicketSeller ticketSeller) {
this.ticketSeller = ticketSeller;
}
public void enter(Audience audience) {
ticketSeller.toSell(audience);
}
}
Theater
에서는 이제 TicketSeller가 하는 일을 직접 처리할 필요가 사라진 것
캡슐화
- 개념적으로나 물리적으로
객체 내부의 세부적인 사항을 감추는 것
변경하기 쉬운 객체를 만듦
으로써, 객체와 객체 사이의결합도를 낮추는 것
인터페이스와 구현
으로 나누고인터페이스만 공개하는 것을 원칙
으로 함
Audience가 직접 bag 처리
public class TicketSeller {
private TicketOffice ticketOffice;
public TicketSeller(TicketOffice ticketOffice) {
this.ticketOffice = ticketOffice;
}
public void toSell(Audience audience) {
ticketOffice.plusAmount(audience.buy(ticketOffice.getTicket()));
}
}
public class Audience {
private Bag bag;
public Audience(Bag bag) {
this.bag = bag;
}
public Long buy(Ticket ticket) {
if(bag.hasInvitation()) {
bag.setTicket(ticket);
return 0L;
}else {
bag.setTicket(ticket);
bag.minusAmount(ticket.getFee());
return ticket.getFee();
}
}
}
Audience가 직접 bag을 처리하기 때문에
외부에서 Audience가 bag을 소유하고 있다는 사실
을 더 이상 알 필요가 없음
Theater의 결합도가 줄어든 것을 확인
할 수 있음
이는 Audience, TicketSeller가 해야할 일을 직접 하는
자율적인 존재
가 되었기 때문
처음 코드 보다 이해하기 쉽고 유연한 설계
를 할 수 있는 것을 확인
객체 내부의 상태
를캡슐화
하고객체 간
에 오직메시지를 통해서만 상호작용
하도록 하는 것
Theater
는 TicketSeller의 sellTo 메시지를 이해하고 응답
하는 것
TicketSeller
는 Audience의 buy 메시지를 이해하고 응답
하는 것
이렇게
밀접하게 연관된 작업만을 수행
하고연관성 없는 작업은 다른 객체에게 위임하는 객체
를응집도가 높은 객체
라고 함
응집도를 높이기 위해서는 객체 스스로 자신의 데이터를 책임져야 함
즉, 자율적인 존재
가 되는 것
휼륭한 객체지향 설계
는외부의 간섭을 최대한 배제
하고메시지를 통해서만 협력
하는자율적인 객체들의 공동체를 만드는 것
- 프로세스
- 수정 전 Theater의 enter 메서드
- 즉, 각
데이터들의 변경, 수정 등이 일어나는 공간
- 데이터
객체
가 가지고 있는어떠한 값이나 상태
프로세스와 데이터
를별도의 모듈에 위치
시키는 방식
ex) 프로세스 - Theater, 데이터 - Audience, TicketSeller 등
관람객과 판매원
은 단지 수동적인 존재
예상을 쉽게 벗어날 수 있기 때문
에 원활한 소통이 어려움
변경하기 어려운 코드
를 양산하여 버그
가 일어나기 쉽다
데이터와 프로세스
를동일한 모듈 내부에 위치
하여 프로그래밍 하는 방식
한 객체 내
에서 데이터와 프로세스를 동시에 처리
함으로써, 자신의 할 일은 자신이 처리하는 자율적인 존재
가 됨자율적인 존재
가 됨으로써, 변경이 쉽고 알아보기 쉬운 코드를 만들 수 있다.
캡슐화
를 이용해의존성을 적절히 관리
함으로써객체 사이의 결합도를 낮추는 것
기능
을 가리키는 객체지향 세계의 용어
Theater
에서 책임이 집중
되어 있었다.캡슐화
를 통해 ticketSeller에게 책임을 부여
함으로써, 책임을 분산
시킬 수 있었다.각 객체
가 자신이 맡은 일을 스스로 처리함
으로써, 책임이 이동
한 것
객체지향 설계
에서는각 객체가 할 일
은자신 스스로 책임
진다. 즉, 프로세스와 데이터가 한 모듈에서 모두 처리되는절차 지향적 설계
에서프로세스와 데이터는 한 객체 내에서 처리
함으로써객체 지향적 설계
로 변경할 수 있고 이 과정에서책임의 이동
이 이뤄지는 것이다.
객체 지향의 핵심
은적절한 객체에 적절한 책임을 할당
하는 것이다. 적절한 객체에 적절한 책임을 할당함으로써 이해하기 쉬운 구조와 읽기 쉬운 코드를 얻게 되는 것
자율적인 객체
로 만듬자율성이 증가
되었지만 결합도와 의존성도 함께 증가
TicketOffice의
자율성
보다는Audience의 결합도를 낮추는 것이 더 중요
하다!
실세계
에선 자율적인 존재가 아님
객체지향 관점
에서는 자신의 일을 스스로 처리하는 자율적인 존재
능동적이고 자율적인 존재
로 SW 객체를 설계
하는 원칙
휼륭한 객체지향 설계
를 위해선생명이 없는 수동적인 존재
라고 하더라도객체지향의 세계
로 넘어오는 순간생명과 지능을 가진 싱싱한 존재
로 다시 태어난다.
설계
란코드를 배치
하는 것이다.
변경 전 코드 & 변경 후 코드
전체적으로
모두 소극장에 방문한 관람객을 입장시키는 작업을 수행
하는 것은동일함
1. 변경 전 코드
데이터와 프로세스를 나누어
별도의클래스에 모두 배치
2. 변경 후 코드
필요한 데이터
를보유한 클래스
안에프로세스를 함께 배치
서로 다른 설계
를 가진 것
좋은 설계
란오늘 완성해야 하는 기능
을 짜야하는 동시에내일 쉽게 변경할 수 있는 코드를 짜야하는 것
,오늘 요구하는 기능을 온전히 수행
하면서내일의 변경을 매끄럽게 수용
할 수 있는설계
- 객체 지향 프로그래밍은 의존성을 효율적으로 통제할 수 있는 방법을 제공함으로써, 요구사항 변경에 좀 더 수월하게 대응할 수 있는 가능성을 보여줌
- 또한, 코드 변경이라는 측면에서 다른 방법들에 비해 안정감을 줄 수 있다!
- 객체지향 세계에선 애플리케이션은 객체들로 구성되며 애플리케이션의 기능은 객체 간 상호작용을 통해 구현
- 객체들 사이의 상호작용은 객체 사이의 주고 받는 메서드로 표현
- 이를 통해 세상을 바라보는 방식 대로 코드를 작성할 수 있다.
휼륭한 객체 지향 설계란 협력 하는 객체 사이 의존성을 적절하게 관리하는 설계다. 세상에 엮인 것이 많은 사람일 수록 변하기 어려운 것처럼 객체가 실행되는 주변 환경에 결합될수록 변경되기 어려워진다.
진정한 객체 지향 설계로 나아가는 길은 협력하는 객체들 사이의 의존성을 조절하여 변경에 용이한 설계를 만드는 것이다!