새로운 내용을 공부할 때
새로운 내용의 공부를 시작할 때 용어의 정의를 이해하지 못하거나 정확하게 알지 못한다면 그 용어가 포함된 문장을 이해하지 못합니다.
작은 단어 하나가 내용을 이해하지 못하게 하기 때문에 용어를 정확하게 이해하는 것이 중요합니다.
주간 회고
📚 Readable-code 학습 회고 2주차
목차
1. 강의 수강
- 일주일간 강의 요약 정리
- 일주일간 강의 회고
- 다음 주에 학습목표
2. 미션
- 미션을 해결하는 과정
- 어떤 관점에서 접근했는지
- 문제를 해결하는 과정
- 왜 그런 식으로 해결했는지
- 미션 해결에 대한 간단한 회고
강의 수강
강의 요약
추상은 하나의 문단을 한 문장으로 정리하기 위해 이 단락의 주제를 나타내는 것.
우리는 추상화 레벨을 높여 가독성을 높이고 중요한 내용을 표현합니다.
구체적인 구현 코드를 내부로 숨기기 때문에 사용자에게 불필요한 정보를 최소한으로 노출하게 해야합니다.
잘못된 추상화는 오히려 사용자의 가독성을 떨어뜨리고, 내부 기능을 확인하는 과정이 발생합니다.
- 객체지향은 내부 상태나 기능을 숨기고 중요한 추상 인터페이스만 노출하기 때문입니다.
사용자 관점에서 내부 로직을 알지 못해도 메서드 시그니처를 통해 충분히 알 수 있도록 해야합니다.
그리고 객체지향 코드가 항상 정답은 아닙니다.
객체지향 프로그래밍은 요구사항으로 변경되는 환경에 기존 코드를 변경하지 않고 확장할 수 있다는 장점이 있습니다.
소프트웨어에 요구사항이 없는 경우는 거의 없지만, 항상 객체지향이 정답이 아니라는 것을 말해주고 계십니다.
객체의 책임과 응집도를 묶기 위해서 사용자의 요구사항이 변경 될 경우 변경되는 지점을 하나로 묶는 것도 방법입니다.
화면에 출력하고, 사용자에 입력을 코드로 변환하는 과정은 input, output 으로 다른 역할이라고 할 수 있습니다.
사용자의 입력을 받기 위해 콘솔에 출력하는 문자열과 사용자의 입력을 파싱하는 input 클래스 모두 같이 수정됩니다.
이 두 객체 각각은 역할이 다르지만 하나의 책임(사용자의 스터디카페 이용권 선택받기)으로 묶으면 응집도도 올라가게 됩니다.
관점의 차이가 신기했습니다.
구체적인 동작 방식을 추상화를 하니 인터페이스도 동작 방식이 메서드 명에 녹아있게 되었습니다. 이용권 파일 읽기 기능을 추상화하여 이용권 읽기가 되니 다른 이용권이 추가되면 인터페이스에 매서드 추가가 되고 처음 만들어진 이용권 파일 읽기 클래스 메서드에 추가됩니다. 스터디 카페 이용권 읽기 클래스이기 때문입니다. 계속 이용권에 대한 변경이나 추가 사항으로 확장되면 클래스는 점점 메서드가 추가되고 인터페이스 메서드도 추가됩니다. 구현 방식을 추상화하니 이렇게 인터페이스도 구현체에 결합이 생긴 기분이 듭니다.
구현체를 통해 추상화하는 방법에 구현 방식이 포함되지 않도록 하는 것이 방법일 수 있습니다.
이용권 읽기 인터페이스가 아니라 좌석 정보 제공 인터페이스, 사물함 정보 제공 인터페이스를 추가하니 내부에서 어떤 구현 방식을 사용하더라도 똑같이 결과를 받아올 수 있게 되었습니다.
능동적으로 읽기
코드를 읽을 때 단순히 눈으로 읽는 것이 아니라 문맥에 따라 개행이나 주석, 메서드 추출로 메서드를 분리하여 도메인 정보를 정확하게 얻는 것이 중요하다고 합니다.
이 부분은 저도 정말 많이 공감하고 있습니다.
메타인지
제 머리 속에 아하 모먼트가 동작하게 된 키워드 입니다.
메타인지 자기가 아는 영역인지, 존재 유무만 아는지, 아예 어떤지 감도 안오는 경우로 나눌 수 있습니다.
아는 영역과 설명할 수 있는 영역은 100%를 만족하기 어려우므로 적절한 비율을 맞추면 좋다고 합니다.
강의 회고
제가 그동안 리팩토링을 하면서 고민하던 내용을 깔끔하게 정리하게 된 주간입니다.
객체지향 프로그래밍에서 어디까지 객체로 묶어야하는 지 고민이 많았습니다.
예를 들어, inputHandler, outputHandler 두 클래스를 하나로 뭉쳐야할지 고민했습니다.
하나의 관심사를 가지고 있다는 건 생각을 했습니다.
어차피 inputHandler를 수정하면 outputHandler도 수정해야한다.
수정사항이 생기는 부분을 같이 묶고 내부 상태를 같이 사용하면 응집도도 높아지고 테스트도 하기 편해질거같다.
생각만 했습니다.
inputHandler은 이용권 정보 파일(scv)을 읽는 책임이 있기 때문에 다른 클래스의 필드로 넣는게 맞는지 확신이 서지 않았습니다.
이제는 관심사에 대해서 어느정도 동일한 변경사항으로 수정해야한다면 같은 오브젝트에서 관리하는게 맞다는것을 알게되었습니다.
관점의 차이에서도 머리가 띵! 했습니다.
구체적인 방식을 추상화하다보니 인터페이스도 역할이 아니라 동작 방식에 대한 추상화가 되어있었습니다.
그러면 인터페이스를 의존하는 다른 클래스는 인터페이스만 보고도 어떤 파일을 읽어오는지 알게됩니다.
DIP에 따르면 상위 모듈은 하위 모듈을 의존하면 안되고, 상위 모듈 과 하위 모듈은 모두 인터페이스를 의존해야합니다.
구체적인 방식이 인터페이스 표현되는 것을 표현하기 위한 거라면 괜찮지만
그게 아니라 추상적으로 표현하려고 한거 였다면 수정해야합니다.
함께 자라기 - 탑 다운 방식에 대한 회고
저는 개발자로 일을 하면서 제가 해야하는 프로젝트는 요구사항이 명확한게 좋았습니다.
회사에서 필요한 기능을 만드는데 어떤 기능이 필요한지 정확하게 모른다는 게 저로서는 이해가 안되었습니다.
제가 받은 프로젝트를 개발하는 시간보다 오히려 기획자와 커뮤니케이션 하는 과정이 더 길때도 많아지다보니
기획자가 중요하게 생각하는 프로젝트가 아닌건가 ? 라는 생각도 종종 들기도 했습니다.
최근 신규 프로젝트가 기획자가 아닌 영업팀에서 필요하다는 기능을 요구했고
단 글자수 200 글자 내외로 간단하게 요구를 했습니다.
기획에는 어떻게 사용하는지, 무슨 목적인지, 언제 사용하는지, 누가 사용하는지 내용이 없고 단순 기능만 만들어달라는 기획이였습니다.
처음에는 이런 생각이였습니다.
그냥.. 만들어달라는 기능만 만들자
그런데 누가 쓰고, 어떻게 쓰는지는 알아야할 거같아서 회의에 참석한 팀장님들에게 돌아다니면서 물어봤습니다.
개발 팀장님, 기획 팀장님, 임원분에게 물어보면서 어떻게 기획이 되었고, 누가 사용하게 되는지 물어보고 나서
프로세스를 구체적으로 만들었다가 다시 추상적으로 표현하면서 보이지 않았던 신규 프로젝트의 구조가 보이기 시작했습니다.
프로젝트를 다시 들여다보니 아무 생각없이 개발하던 것보다 프로세스가 단순해졌고, 기존 프로젝트에도 적용한다면 유지보수와 사용자들도 편하도록 전체 구조가 바뀌게 되었습니다.
강사님이 말씀하신게 이런게 아닌가 싶습니다.
탑다운 방식으로 주어진 선택지 내에서 해결하는 방법은 빠르게 개발을 시작할 수 있으나
추상과 구체를 오가면서 깨닫는게 있다는게 이런게 아닌가 싶었습니다.
드나드는 것이 생각보다 저에게 많은 인사이트를 주었습니다.
다음 학습 목표
테스트 코드를 사용한다는 의미가 무엇인지 알고 싶습니다.
테스트 코드가 불필요한 짐이 되지 않기 위해서는 어떻게 관리해야하는지 공부하고 싶습니다.
추가로 기술을 배우고 기존과 달라진게 있다면 바로 정리하는 습관을 길들이겠습니다.
미션
미션을 해결하는 과정
어떤 관점에서 접근 했는지
저는 미션 코드의 큰 그림을 스프링 MVC 패턴과 톰캣 & 스프링 컨테이너 이라고 생각하며 접근을 시도했습니다.
톰캣은 StudyCafeApplication
이며 사용자의 요청과 응답을 줄 수 있는 환경을 제공한다.
스프링 컨테이너는 StudyCafePassMachine
으로 보고 사용자의 요청과 응답을 서비스 계층에 변환하여 전달하는 역할이다.
내부 구현 코드는 Service
계층이기에 외부 입력과 출력에 영향을 받지 않도록 해야한다.
문제를 해결하는 과정은 무엇이었는지
패스입력을 변환 하기 전까지는 컨트롤러 계층이라고 생각했습니다. 요청 파라미터를 변환하여 서비스 계층이 이해할 수 있는 언어로 변환하여 전달한다.
서비스 계층은 외부가 어떠한 방식으로 요청을 받든지 상관없이 자신이 기능을 제공하기 위해 필요한 파라미터를 추상화하여 표현한다
이 두 관점을 가지고 객체 관심사로 역할을 나누려고 했습니다.
문제가 입력과 출력이 이미 역할이 부여된 것이라고 생각을 하다보니 객체를 합치기 어려웠고 리팩토링 하는 과정에 추상화로 묶기 어려웠습니다.
그래서 아쉽게도 목적만 들어내기 위한 메서드 추출이 되었고 코드는 복잡해지기만 했습니다.
왜 그런 식으로 해결했는지 내용
스프링은 객체지향 프로그래밍을 하기 위한 다양한 기술을 제공하는 프레임 워크입니다.
사용자가 원하는 이용권 조회 및 이용권 금액 계산, 할인 정책은 핵심 비즈니스 로직인 service 계층으로 바라본다.
사용자의 입력과 출력은 HTTP 프로토콜에서 문자열을 필요한 정보와 서비스 계층에서 필요한 양식으로 변환하는 컨트롤러 구조
파일에서 읽던, 메모리에서 읽던, DB에서 읽던 결과는 서비스 계층이 읽을 수 있는 데이터 구조로 반환하는 리포지토리 구조
이렇게 바라보면서 코드를 작성하면 스프링 MVC 구조로 객체지향적이면서 유지보수하기 좋은 코드로 작성될 수 있다고 생각했습니다.
미션 해결에 대한 간단한 회고
미션해결과 중간정검을 통해 배운게 있습니다.
직접 해보자.
익숙해질때까지 하자.
지금까지 학습 방식은 강의를 보고 끄덕끄덕, 그리고 인프런에서 보여주는 100% 게이지를 보며 만족했습니다.
실제 예제 코드를 리팩토링하려니 뇌 메모리에 그동안 배운 정보가 로드되었습니다.
코드로 출력하려고 하니 2시간째 코드만 바라보고 있었습니다.
뇌 속에 정보는 많은데 익숙하지 않으니 키보드로 출력이 되지 않았습니다.
강사님이 말씀하신 메타인지 중 들어본적이 있는 영역까지만 도달한거 같습니다.
미션 해결을 하면서 강의만 듣고 이해한 것은 제가 학습한게 아니라는 것을 느꼈습니다.
출처
인프런 워밍업 클럽
인프런 워밍업 클럽 스터디 3기 - 백엔드 클린코드, 테스트 코드(Java, Spring Boot)
강의 링크
Readable Code: 읽기 좋은 코드를 작성하는 사고법
[Practical Testing: 실용적인 테스트 가이드](https://inf.run/g8nxP
댓글남기기