책은 객체지향적으로 생각하는 것을 가장 중점에 두고 서술하고 있다. 객체란 무엇인지 혹은 클래스란 무엇인지에 대한 설명을 시작으로 은닉, 상속, 합성, 다형성 등을 설명해준다. 글의 중간 중간에 들어가는 uml 이라던지 혹은 특정 프로그래밍 언어로 작성된 코드를 자주 보여주고 있다. 다만 해당 책의 핵심은 우리가 현실세계 문제를 객체지향으로 해결하기 위한 단순 코드를 어떻게 작성할 것인지에 보단 객체지향적으로 생각하는 방식의 중요성을 지속적으로 강조하고 있다.

 

책의 내용이 너무 기초적일수 있지만, 그런 기초를 다시한번 상기시키는 것은 매우 중요하다고 생각한다. 요즘 의식하지 않고 프로그래밍을 한다는 느낌을 스스로 받고있는데, 이러한 책을 읽음으로써 다시금 의식하고 프로그래밍을 수행할 수 있도록 해야겠다.

 

책을 읽으면서 밑 줄을 좀 그었다. 아래는 밑 줄 그은 내용을 그대로 받아적기보다는 그 밑 줄을 바탕으로 생각해본 개인적인 의견들이다.

 

-

1장 ~ 3장

 

좋은 객체지향설계에서 객체는 여타 객체와 상호작용 하는 데 필요한 인터페이스만 나타내야 한다.

객체는 행위와 속성의 집합이다. 객체에 대한 속성은 해당 객체의 행위를 통해서만 변경이 일어나야하며, 외부에서 해당 객체를 이용하려고 한다면 특정 인터페이스를 기반으로 기능을 수행할 수 있도록 한다. (tell don't ask). 객체와 객체 사이의 협력은 속성을 달라고 요청하지 말고 해당 속성을 가진 객체가 일을 하도록 시킨다. 그 일 (behavior) 은 구현부에 구체화되어 있다.

 

좋은 인터페이스는 구현부가 바뀌어도 사용자 코드를 변경하지 않는다.

외부에는 인터페이스만 노출되고 실제 구현부는 내부 객체에서 처리하도록 한다. 그렇게 한다면 클라이언트는 인터페이스를 통해서만 해당 객체와 통신할 수 있다. 내부의 구현을 알 필요가 전혀 없다.

 

객체지향 설계 과정은 반복되어야 하며, 처음부터 정확히 맞출 필요는 없다.

 

가능한한 사용자 인터페이스를 적게 제공한다.

외부에 노출되는 인터페이스의 접점을 최소화하라는 의미로 받아들일 수 있다. 접점이 증가되면 관리포인트가 늘어나는 것이고 이는 코드의 유지보수성이 올라감을 생각할 수 있다. 그리고 그로인해 리소스 낭비가 커지게 됨을 짐작할 수 있다.

 

4장 ~ 6장

 

클래스는 자체 속성을 잘 보호해야 한다.

tell don't ask 원칙과 비슷하다고 볼 수 있는데, 이점은 데이터의 무결성과 더불어서 효율적인 디버깅을 제공한다고 한다. 결국 외부에서 변경점이 가해지는것이 아니라 내부에서 변경이 가해진다면 내부에서 변경을 가하는 외부 노출 인터페이스만 살펴보면 된다는 의미로 해석할 수 있다.

 

잘 작성된 코드는 그 자체로 가장 좋은 문서가 된다.

나는 그렇다고 생각하지 않는다. 일부 코드는 잘 작성이 되었더라도 전체적인 비즈니스 로직을 고려했을 때, 일부 주석이 필요하다고 본다.

 

구조적 코드를 객체지향 코드로 래핑한다.

일반적으로 레거시를 손 본다고 하면 아예 뜯어고치는 방향으로 나는 생각을 해왔는데, 책을 살피니 레거시를 래핑해서 인터페이스만 노출하고 내부 구현부는 그대로 이용할 수 있도록 하는 방법도 설명하고 있다. 또한 이와 관련해서 데코레이터 패턴이랑 어댑터 패턴을 책에서 언급하고 있다.

 

7장 ~ 9장

 

상속과 합성에 익숙해지기. (코드의 재사용성)

7장은 전반적인 상속과 합성을 빠르게 훑고 넘어간다. 상속과 합성은 코드의 재사용성을 증대시키는데, 코드의 재사용성은 "장황한 작업에 소비하는 시간과 에너지를 절약하는 전형적 기법이다." 이다. (위키) 여기서 코드의 재사용성을 중요시해서 상속의 기능을 너무 남발하거나 또는 합성을 남발하는 것은 모델의 복잡도를 증가시킨다. 향후 어떻게 컴포넌트가 구축될 것인가에 대해 고려하여 적당한 시점에서 트레이드 오프가 필요하다. 적당한 시점이라면 어떤 시점일까 ?

 

앞으로도 구축될 가능성이 있는 것들에 한해서, 모두가 납득할만한 구축 범위 내에 포함되는지 여부.

 

해당 장을 읽으면 상속은 명확한 관계가 성립된 클래스 간에 필요하고, 만약 쓰게 되더라도 슈퍼클래스의 구현부의 변화가 서브클래스에도 영향을 끼치기 때문에 코드의 재사용성은 좋을지 모르더라도 슈퍼클래스와 서브클래스 사이의 간의 캡슐화는 약해진다. 외부에서는 캡슐화가 잘 되어있을지라도 둘 사이에는 상속이라는 조건 하에 코드 변경에 대한 파급력이 쉽게 갈 수 있기 때문이다.

 

책을 읽다보면 상속은 모델/데이터(attribute) 로 이용하고 행위(behavior) 는 인터페이스로 추상화시켜서 구현(implentation) 하는 것을 기준으로 이야기하고 있다. 

 

그럼 상속으로는 코드의 재사용성을 쓰지 말라는 이야기인가? 그건 또 아니다. 현실세계의 문제를 잘 해결할 수 있는 방향으로 적절히 쓰길 권장하고 있다.

 

일반적으로 객체는 스스로 어떤 역할을 해야한다.

객체에 어떤 인자값을 주지 않더라도 해당 객체는 독립적인 일을 스스로 해야한다. 그 객체가 상위 클래스에 대한 상속을 받고 있는 서브클래스라고 한다면 더더욱. 스스로 책임을 질 수 있는 객체를 만드는 것이 좋아보인다.

 

+) 과거에 썻던 글

20180125 IS-A & HAS-A relationship (2020-10-04)

20180128 Loose Coupling & High Cohesion
20180129 Loose Coupling & High Cohesion 2

 

무려 3년전에 썼던 글이다. 다시 살펴볼 수 있는 좋은 시간이었다.

Posted by doubler
,