티스토리 뷰

일상

[책] 오브젝트를 읽고 - 1

애쿠 2024. 3. 3. 19:25

주니어 개발자들이 으레 그렇듯, 나도 결과에 치중해서 개발하는 시기가 있었다.

 

이제 백엔드 리드급으로 넘어오게되면서, 단순 구현보다는 유지보수나 확장성에 대해 많은 고민을 하게 됐다.

 

그러다보니 자연스럽게 패턴과 설계에 대해 관심이 가게 됐고 추천받은게 이 책이었다.

 

몇 년간 자바를 주언어로 개발을 했기 때문에, 객체지향 프로그래밍에 대한 어느정도 알고 있다고 생각했다.

 

그래서 객체지향 개념을 잘 사용하고 있나에 대한 고민은 딱히 하지 않았었다.

 

하지만 이 책을 보면서 객체지향 개념에 대해 다시한번 정리하게 됐다.

 

사실 갑자기 백엔드 개발을 하게 되면서 자바를 갑자기 쓰게 됐었다.

 

그래서 언어의 특징인 객체지향을 완벽하게 숙지 못하고 시작한 게 이유지 싶다.

(캡슐화,  다형성, 상속, 합성 등 용어에 대한 정립도 제대로 되어있지 않았다.) 

 

이 책에서 코드를 기준으로 전개하는 방식은 꽤 괜찮았지만, 처음에 엉망으로 짜고 개선해가는 방식은 별로 좋아하지 않아서(Interface 사용법이나 객체에 어느정도의 책임을 부여해야하나에 대한 부분들은 꽤 좋았다.)

 

키워드와 인상깊었던 문구들 위주로 정리해보려고 한다. 


1. 소프트웨어 분야에서는 패러다임은 공존할 수 있다. 절차지향과 객체지향은 상호보완적이다.
2. 소프트웨어 분야에서는 이론보다 실무가 먼저다.
소프트웨어 모듈의 3요소(로버트 C. 마틴)
1. 실행 중 제대로 동작해야 함
2. 쉽게 변경할 수 있게 구현
3. 쉽게 이해할 수 있는 코드를 작성
데이터와 프로세스가 동일한 모듈 내부에 위치하도록 프로그래밍하는 방식을 객체지향 프로그래밍이라 한다.

 

좋은 설계란?

우리가 짜는 프로그램은 두 가지 요구사항을 만족시켜야 한다. 우리는 오늘 완성해야하는 기능을 구현하는 코드를 짜야하는 동시에 내일 쉽게 변경할 수 있어야 한다. 
객체간 의존성과 캡슐화를 적절히 관리해 객체 사이의 결합도를 낮추는게 좋은 설계 방식
설계가 유연해질수록 코드를 이해하고 디버깅하기는 점점 더 어려워진다. 역으로, 유연성을 억제하면 코드를 이해하고 디버깅하기는 쉬워지지만 재사용성과 확장 가능성은 낮아진다. 훌륭한 객체지향 설계자로 성장하기 위해서는 항상 유연성과 가독성 사이에서 고민해야한다. 무조건 유연한 설계도, 무조건 읽기 쉬운 코드도 정답이 아니다.

 

다형성

실제로 어떤 메서드가 실행될지는 메시지에 따라 달라진다. 어떤 메서드가 실행될지는 실행시점에 결정되며 이를 동적 바인딩이라고 표현한다.

 

객체지향 프로그래밍 시점에서의 상속의 단점

1. 자식-부모 클래스의 결합도가 너무 높으며, 부모 클래스의 매서드가 자식에게 노출되어 캡슐화에도 위배된다.
2. 유연하지 않은 설계 : 부모-자식 클래스 관계가 컴파일 시점에 결정됨
-> 인터페이스를 이용한 합성을 사용하자(상속을 무조건 사용하지 말라는 말 X)

 

협력, 책임, 역할

객체들이 애플리케이션의 기능을 구현하기 위해 상호작용하는 것을 협력
객체가 협력에 참여하기 위해 수행하는 로직은 책임
객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행하는 역할
객체에게 적절한 책임을 할당하는게 객체지향 프로그래밍의 핵심
객체지향 패러다임에 갓 입문한 사람들이 가장 쉽게 빠지는 실수는 객체의 행동이 아니라 상태에 초점을 맞추는 것이다. 상태를 먼저 정의하고, 상태에 필요한 행동을 결정하면 안됨
책임에 초점을 맞춰서 설계할 때 직면하는 가장 큰 어려움은 어떤 객체에게 어떤 책임을 결정하기가 쉽지않다는 것이다. 책임 할당 과정은 일종의 트레이드오프 활동이다. 동일한 문제를 해결할 수 있는 다양한 책임 할당 방법이 존재하고, 어떤 책임 할당 방식이 최선인지는 상황과 문맥에 따라 결정된다.
데이터 주도 설계보다는 책임 주도 설계로 구현하라
데이터보다 행동을 먼저 결정, 협력이라는 문맥 안에서 책임을 결정

 

캡슐화

1. 객체 내부의 구현을 외부로부터 감추기 위함
2. 불안정한 부분과 안정적인 부분을 분리
3. 변경 가능성이 높은 부분을 객체 내부로 숨김

 

퍼블릭 인터페이스의 품질에 영향을 미치는 원칙과 기법

1. 디미터 법칙
"오직 하나의 도트(.)만을 사용하라" (강제 X), 객체간 협력 경로를 제한(입출력 객체를 명시).
불필요한 그 어떤 것도 다른 객체에게 보여주지 않음
자료구조라면 내부구조를 봐야하므로 어쩔 수 없음. 객체에만 적용되지만 객체도 내부 구조를 외부로 노출시키지만 않는다면 허용
2. 묻지 말고 시켜라
동작을 지시하도록 인터페이스의 메시지를 작성한다. 객체가 어떻게 작업하는지 노출하지 않기 때문
3. 의도를 드러내는 인터페이스
매서드의 이름을 '어떻게'가 아닌 '무엇을' 하는지 명시해라.
4. 명령-쿼리 분리
명령(프로시저 - 값을 변경 시킴 & return 못함), 쿼리(함수 - 객체의 값을 변경시키지 않음 & return O)
= 질문이 답변을 수정하면 안된다.

 

부수효과

입력값을 변경시키는 일 - 수학의 세계에서는 존재 x, 프로그래밍 세계에서는 대입문을 통해 변경 가능

 

참조 투명성

표현식 e가 있을 때 e가 존재하는 모든 위치의 e를 변경하더라도 결과가 같아야한다.

 

함수형 프로그래밍

부수효과 x. 참조 투명성을 극대화해서 명령형 프로그래밍에 비해 결과를 예측하기 쉬움

 

책을 통해 배운점

클린코드와는 다르게 나름대로 이 책은 내가 고민하고 있는 부분들을 꽤 긁어줬다.

 

무엇보다 계속해서 강조하는 두 문구가 있는데, 이 부분이 나한테는 굉장히 와닿았다.

1. 설계는 트레이드오프의 산물이다. 적절한 트레이드 오프로 설계를 할 수 있는게 초보자와 숙련자의 차이다.
2. 원칙은 반드시 지킬 필요가 없다. 원칙이 현재 상태에 위배된다면 과감하게 원칙을 포기해라.

 

개발적으로는 interface를 이용한 확장성 있는 개발이 인상적이었다.

 

그동안 Enum을 사용하던 부분들이 많았는데 interface로 치환하면 더 좋은 구조가 나올 것 같다는 생각이 들었다.

 

이 내용은 바로 반영해서 리팩토링할 계획이다.

 

그리고, 접근제어자를 제대로 설정해둘 필요성을 느꼈다.

 

현재는 대부분 @Data를 박아뒀는데, setter가 필요없는 객체가 많기 때문이다. 매서드는 대부분 public이고..

 

좀 이상하다 느낀 점은 캡슐화를 지나치게 강조한다는 느낌을 받았다.

(상황에 맞게 개발하라며?)

 

마치며

싱숭생숭한 일이 많이 생겨서 책을 읽었는데 잘한 선택인 것 같다.

 

7장이 조금 재미없는 내용이 나와서 멈추고 6장까지의 내용을 정리한 글이다.

 

책을 읽으며 무엇보다 객체지향 프로그래밍에 대한 기본적인 부분이 많이 보완 됐다.

 

반 정도 남은 것 같은데, 언제 다 읽을 수 있을지 모르겠다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함