엘레강트 오브젝트 1-1

2021-07-21

엘레강트 오브젝트

새로운 관점에서 바라본 객체지향

Yegor Bugayenko | 조영호 역

회사 동료가 추천해 준 책으로 책이 얇고(183p) 흥미로운 주제라서 읽게 되었다.
책을 읽으면서 요약내용을 해당 블로그에 작성할 예정으로,
한번 훑듯이 읽어봤을때는 제가 기존에 가지고있던 개념과 상당히 충돌되는 부분이 많아서 어떤면에서는 흥미로웠고 어떤면에서는 불쾌하기까지 (작가가 상당히 강경함) 하면서 읽었지만, 세상에 틀린의견은 없고 다른의견만 존재한다는 나름 제 가치관에 따라 즐겁게 읽고 요약내용을 남겨본다.

1장 출생

1.1 -er로 끝나는 이름을 사용하지 마세요

Java에서 제공하는 new 연산자가 충분히 강력하지 않음.
new 연산자로 할 수 있는 유일한 작업은 객체의 인스턴스를 생성하는 것일 뿐,
유사한 객체가 이미 존재하거나 재사용 가능한 지를 확인하지도 않으며,
new 가 동작하는 방식을 변경할 수 있는 어떤 매개 변수도 제공하지 않음

팩토리 패턴은 new 연산자를 대신해서 사용할 수 있는 더 강력한 옵션이기는 하지만,
개념적으로 팩토리 패턴과 new 연산자는 동일.
Java에서 팩토리 패턴은 new 연산자를 확장한 것 처럼 동작.
new연산자가 실행되기 전에 부가적인 로직을 더 할 수 있기 때문에, 좀더 유연하고 강력하게 만들 수 있다.

1
2
3
4
5
6
7
8
9
10
11
class Shapes {
public Shape make(String name) {
if (name.equals("circle")) {
return new Circle();
}
if (name.equals("retangle")) {
return new Rectangle();
}
throw new IllegalArgumentException("not found");
}
}

팩토리에서도 객체를 생성하는 최종 단계에서는 여전히 new 연산자를 사용함.
핵심은 개념상 팩토리 패턴과 new 연산자가 크게 다르지 않다는점.
클래스는 필요할 때 객체를 꺼낼 수 있고,
더 이상 필요하지 않은 객체를 반환 할 수 있는 객체의 웨어하우스로 클래스를 바라보는것을 추천

클래스 = 객체의 팩토리

클래스를 객체의 능동적인 관리자로 생각해야 한다는 것,
클래스는 객체를 꺼내거나 반환할 수 있는 위치이기 때문에,
클래스를 저장소 또는 웨어하우스라고 불러야 함

클래스의 네이밍방법에 대해 클래스의 객체들이 무엇을 하고있는(doing)지를 살펴본 후 기능(functionality)에 기반해서 이름을 짓는방법은 잘못된 방법.

1
2
3
4
5
6
7
8
9
class CashFormatter {
private int dollars;
CashFormatter(int dlr) {
this.dollars = dlr;
}
public String format() {
return String.format("$ %d", this.dollars);
}
}

이런식의 네이밍 원칙은 아주 잘못된 방식이지만 매우 인기가 많음
클래스의 이름은 객체가 노출하고 있는 기능에 기반해서는 안됨.
클래스의 이름은 무엇을 하는지가 아닌 무엇인지에 기반해야함
다음 예제와 같이

1
2
3
4
5
6
7
8
9
class Cash {
private int dollars;
Cash(int dlr) {
this.dollarws = dlr;
}
public String usd() {
return String.format("$ %d", this.dollars);
}
}

객체는 그의 역량(capability)으로 특징지어져야함.
제가 어떤 사람인지는 키, 몸무게, 피부색과 같은 속성(attribute)이 아니라, 제가 할 수 있는일(what I can do)로 설명해야함.

여기에 숨어있는 악마는 바로 접미사 ‘-er’
‘-er’로 끝나는 이름을 가진 수많은 클래스가 존재함 Manager, Controller, Helper, Handler, Writer, Reader, Converter, Validator, Router, Dispatcher, Observer, Listener, Sorter, Encoder, Decoder …

객체는 객체의 외부 세계와 내부 세계를 이어주는 연결장치가 아님.
객체는 내부에 캡슐화된 데이터를 다루기 위해 요청 할 수 있는 절차의 집합이 아님.
객체는 캡슐화된 데이터의 대표자(representative)

그렇다면 올바른 클래스의 이름은 어떻게 지어야 할까?

클래스의 객체들이 무엇을 캡슐화 할 것이지,
이 요소들에 붙일 적합한 이름을 찾아야 함.
예를들어 임의의 숫자 리스트가 존재할 때, 이 리스트의 요소 중에서 소수를 찾는 알고리즘을 만단다는 가정 하
오직 소수만으로 구성된 리스트를 얻는 것이 목적이라면,
Primer, PrimeFinder, PrimeChooser, PrimeHelper 등으로 지으면 안됨.
PrimeNumbers라고 지어야함.

요약하면,
클래스의 이름을 붙일 때는 무엇을 하는지(what he does) 가 아닌 무엇인지(what he is)를 생각해야함.
내가 무성슬 하느지와 내가 누군지는 다르다.

https://www.yegor256.com/2015/03/09/objects-end-with-er.html