16. 즉, 구현 기술이 소프트웨어 개발을 주도함으로써
발생되는 여러가지 문제점을 해결하기 위해
도메인 주도적인 방식으로 소프트웨어를 개발할 것을 주장한다.
17. "코드와 모델을 밀접하게 연관시키는 것은
코드에 의미를 부여하고 모델을 적절하게 한다”
출처: eternity 블로그
18. 마틴 파울러는 [UML Distilled 2판]에서 객체지향 설계 안에 존재하는 세 가지
상호 연관된 관점에 관해 설명했다
1. 개념 관점 (Conceptual Perspective)
2. 명세 관점 (Specification Perspective)
3. 구현 관점 (Implementation Perspective)
19. ü 설계는 도메인 안에 존재하는 개념과 개념들 사이의
관계를 표현한다.
ü 도메인은 특정 분야나 주제이며 소프트웨어는 도메인
에 존재하는 문제를 해결하기 위해 개발된다.
ü 이 관점은 사용자가 도메인을 바라보는 관점이다.
ü 실제 도메인의 규칙과 제약을 최대한 유사하게 반영하
는 것이 핵심이다.
개념 관점1
20. ü 사용자의 영역인 도메인을 벗어나 개발자의 영역인
소프트웨어로 초점이 옮겨진다.
ü 도메인의 개념이 아니라 실제 소프트웨어 안에 살아
숨쉬는 객체들의 책임에 초점을 맞추게 된다.
ü 객체가 협력을 위해 “무엇”을 할 수 있는가에 초점
명세 관점2
21. ü 프로그래머인 우리에게 가장 익숙한 관점으로 실제
작업을 수행하는 코드와 연관돼 있다.
ü 객체들이 책임을 수행하는데 필요한 동작하는 코드를
작성하는 것이다.
ü 따라서 프로그래머는 객체의 책임을 "어떻게” 수행
할 것인가에 초점을 맞추며 필요한 속성과 메서드를
클래스에 추가
구현 관점3
22. ‘그러면 3가지를 순서대로
개발하는 것인가요?’
‘아닙니다.
동일한 클래스를 세 가지
다른 방향으로 바라보는 것을
의미합니다’
나초보 김객체
23. 클래스가 은유하는
도메인은 개념 관점
클래스의 공용
인터페이스는 명세 관점
클래스의 속성과
메서드는 구현 관점
클래스
클래스는 세 가지 관점이라는 안경을 통해
다양한 측면을 드러낼 수 있다
바라본다
24. 이 장의 목표는
최종 코드까지의 구현 과정 설명1
개념 관점, 명세 관점, 구현 관점의 의미2
25. 객체지향 패러다임의
가장 중요한 도구는 객체
개발에 들어가기 전 먼저 커피 전문점을 구성하는
요소들에 관해 잠시나마 고민해보자.
커피 전문점을 객체들로
구성된 작은 세상으로
바라보자
44. 커피를 주문하라
메뉴 이름
메뉴 항목을 찾아라
메뉴 이름
커피를 제조하라
메뉴 항목
생성하라
메뉴 항목
커피
손님
메뉴판
바리스타
커피
각 객체들이 수신하는 메시지는
객체의 인터페이스를 구성한다
45. class Customer {
public void order(String menuName) {}
}
class Menu {
public MenuItem choose(String name) {}
}
class Barista {
public Coffee makeCoffee(MenuItem menuItem) {}
}
class Coffee {
public Coffee(MenuItem menuItem) {}
}
커피를 주문하라
메뉴 이름
메뉴 항목을 찾아라
메뉴 이름
커피를 제조하라
메뉴 항목
생성하라
메뉴 항목
커피
손님
메뉴판
바리스타
커피
46. Customer 구현하기
Customer가 어떻게 Menu 객체와 Barista 객체에 접근할 것이냐다.
Customer의 order() 메서드의 인지로 Menu와 Customer 객체를 전달받는 방법
으로 참조 문제를 해결하기로 한다.
class Customer {
public void order(String menuName, Menu menu, Barista barista) {}
}
47. Menu 구현하기
Menu는 menuName에 해당하는 MenuItem을 찾아야 하는 책임이 있다.
이 책임을 수행하기 위해 내부적으로 MenuItem을 관리하고 있어야 한다.
class Menu {
private List<MenuItem> items;
public Menu(List<MenuItem> items) {
this.items = items;
}
public MenuItem choose(String name) {
for (MenuItem each : items) {
if (each.getName().equals(name)) {
return each;
}
}
return null;
}
}
48. Barista 구현하기
Barista는 MenuItem을 이용해서 커피를 제조한다.
class Barista {
public Coffee makeCoffee(MenuItem menuItem) {
Coffee coffee = new Coffee(menuItem);
return coffee;
}
}
49. Coffee 구현하기
Coffee는 자기 자신을 생성하기 위한 생성자를 제공한다.
class Coffee {
private String name;
private int price;
public Coffee(MenuItem menuItem) {
this.name = menuItem.getName();
this.price = menuItem.cost();
}
}
50. MenuItem 구현하기
MenuItem은 getName()과 cost 메시지에 응답할 수 있도록 메서드를 구현한다.
public class MenuItem {
public MenuItem(String name, int price) {
this.name = name;
this.price = price;
}
public int cost() {
return price;
}
public String getName() {
return this.name;
}
}
51. 커피 전문점 코드의 클래스 다이어그램
order(menuName, menu, barista)
Customer
choose(name) : MenuItem
Menu
name
price
Coffee
<<constructor> Coffee(name, price)
makeCoffee(menuItem) : Coffee
Barista
name
price
MenuItem
cost() : int
getName() : String
<<create>>
53. 개념 관점에서
ü 도메인 개념의 특성을 수용하면 유지보수성을 향상
ü 커피를 제조하는 과정을 변경해야 한다면 어디를 수정해야 하는가?
Barista 객체가 커피를 제조할 것으로 쉽게 유추 가능
ü 소프트웨어 클래스와 도메인 클래스 사이의 간격이 좁으면 기능을 변경할 곳을 쉽게 유추
Customer Menu MenuItem
Barista Coffee
54. 명세 관점에서
클래스
공용 인터페이스
ü 외부의 객체가 해당 객체에 접근할 수 있는 유일한 부분
ü 객체의 인터페이스는 수정하기 어렵다는 사실을 명심하라
ü 최대한 변화에 안정적인 인터페이스를 만들기 위해서는
인터페이스를 통해 구현과 관련된 세부사항이 드러나지 않게 해야 한다
55. 구현 관점에서
클래스
속성 메서드
클래스의 메서드와 속성은 구현에 속하며
공용 인터페이스의 일부가 아니다.
ü 구현에 포함
메서드의 구현과 속성의 변경은 원칙적으로
외부의 객체에게 영향을 미쳐서는 안된다
ü 캡슐화
56. 도메인 개념을 참조하는 이유
‘도메인 개념을 참조하는
이유가 뭐예요?’
‘소프트웨어는 항상 변하고
설계는 변경을 위해 존재해’
‘변경이 생겼을 때 코드를
좀 더 수월하게 수정할 수 있기
때문이야’
57. 이번 장에서는
1. 객체지향 설계 안에 존재하는 3가지 관점을 설명
2. 최종 코드까지의 구현 과정 설명
3. 커피 전문점 객체, 타입, 관계, 협력, 인터페이스, 구현 설명