새로운 내용을 공부할 때
새로운 내용의 공부를 시작할 때 용어의 정의를 이해하지 못하거나 정확하게 알지 못한다면 그 용어가 포함된 문장을 이해하지 못합니다.
작은 단어 하나가 내용을 이해하지 못하게 하기 때문에 용어를 정확하게 이해하는 것이 중요합니다.

6 분 소요

📌 2025-03-08 Readable-code 학습 회고

목차

1. 강의 수강

  1. 일주일간 강의 요약 정리
  2. 일주일간 강의 회고
  3. 다음 주에 학습목표

2. 미션

  1. 미션을 해결하는 과정
    • 어떤 관점에서 접근했는지
    • 문제를 해결하는 과정
    • 왜 그런 식으로 해결했는지
  2. 미션 해결에 대한 간단한 회고

강의 수강

강의 요약

개발자는 컴퓨터 프로그램을 작성하여 현실 세계에 발생된 문제를 해결합니다. 문제를 파악하고 문제를 해결하기 위한 방안을 생각합니다. 문제 해결 방안을 컴퓨터가 이해할 수 있는 언어로 작성합니다.

새로운 요구사항이 들어오면 프로그램 내부 구현 코드를 읽습니다. 개발자는 신규 기능 개발보다 유지보수를 할 때가 더 많습니다.

제가 생각하는 코드 작성하는 것은 비문학 소설을 작성하는 것과 동일하다고 생각합니다. 글 내용에는 어떤 내용이 중점인지 설명이 잘되어 있어야 이 책이 주는 정보를 빠르게 파악하기 쉽습니다.

“세탁기”

세탁기를 처음 사용할 때, 가전 제품을 처음 사용할 때 사용 설명서를 읽지 않고 사용할 수 있습니다.

직관적으로 어떤 기능을 제공하는지 아이콘과 옆에 라벨이 붙어있기 때문입니다.

코드도 마찬가지 라고 생각이 듭니다.

세탁기 레버를 돌리는 기능(Method), 세탁기 세탁 옵션에 보이는 숫자나 그림들(fields)에 대한 설명(변수명)만 봐도 알수 있게끔 하는 것이 가독성이 좋아지며 가독성에서 절약한 시간으로 추가 기능을 개발할 수도 있습니다.

  1. 변수명
  2. 메서드명
  3. 메서드 매개변수명과 매개변수 타입
  4. 매개변수 반환값

추상

추상은 구체에서 덜 중요한 것은 덜어내어 중요한 정보만 남기는 것을 의미합니다.

“세탁기”를 돌릴때 전원/시작을 누르면 알아서 기본 설정된 값으로 빨래를 합니다.

이것이 추상이라고 생각합니다

만약 저 버튼이 추상이 되어 있지 않다면 전원을 킨다 그리고 물을 넣는다 그리고 세탁을 한다 그리고 탈수를 한다…

이렇게 모든 내부 과정을 작성하게 되는 것은 사용자로 하여금 불필요한 정보로 가독성을 떨어지게 합니다

class 세탁기 {
	void start(세탁세제 세제,섬유유연제 유연제,보조세탁세제 보조세제){
    1. 전기를 세탁기에 흐르도록 한다.
    2. 세탁기를 회전하여 세탁시간을 파악한다.
    3. 세제통에 물을 넣는다.
    4. 물이  들어가면 세탁을 한다
       :
  }
}

이 과정은 하나로 추상하면 “세탁” 또는 “시작” 이라고 할 수 있을 거같습니다.

추상을 하는 이유는 사용자가 빠른 이해를 도와주고 불필요한 정보를 뇌에서 가져오지 않도록 하여 가독성을 높여줍니다.

객체지향 프로그래밍과 원칙

SOLID는 객체지향 원칙(principle)입니다.

현실 세계에서 원칙이 없다면 비효율적이고 질서가 유지되지 않을거라고 생각합니다.

  • 횡된보도 신호등에 초록불이 들어오면 사람이 건넌다.

  • 우측보행

이런 원칙들이 없다면 사회는 비효율적이고 질서가 없을거라 생각합니다.

원칙이 생긴 이유를 한 문장으로 정리하면

사람들은 현실 세계에서 질서를 유지하고 효율적인 의사결정을 위해, 필요한 시점에 원칙을 만들고 이를 지키도록 시스템을 운영한다.

이 문장을 SOLID 원칙으로 변경해보았습니다.

개발자는 객체지향 세계에서 질서 유지하고 유지보수와 확장을 위해, 필요한 시점에 SOLID 원칙을 만들고 이를 지키도록 한다.

  • SRP
  • OCP
  • LIP
  • ISP
  • DIP

이런 원칙들을 지켜가다보면 객체지향 프로그래밍이 효율적이고 질서가 있게 작성할 수 있기 때문에 학습하는 것이 필요하다고 생각합니다.

사고의 흐름

사고의 흐름이 무슨 의미인지 몰라서 물어봤습니다.

사고의 흐름이란

어떤 개념이나 주제에 대해 생각이 자연스럽게 연결되고 발전하는 과정을 말한다.

예를 들어, 글을 읽거나 쓸 때 논리적으로 앞뒤가 맞고, 하나의 아이디어가 다음 아이디어로 매끄럽게 이어지는 경우 사고의 흐름이 좋다고 할 수 있다.

그러면 개발자가 작성하는 코드가 사고의 흐름이 좋다는 것은 이렇게 정리 할 수 있을거 같습니다.

  1. 논리적으로 전개가 자연스럽다.
  2. 함수나 메서드의 이름만 봐도 어떤 동작을 하는지 예측이 가능하다.
  3. 불필요하게 많은 if-else문이 없이 간결한 구조를 갖는다.
  4. 데이터를 어디서 받아서 가공하고 전달되는지 보인다.

저는 집중의 뇌과학이라는 책을 봤습니다.

책에서 작업공간이라는 단어가 나옵니다.

“사람은 작업 공간이라는 임시 저장소가 있다. 평균적으로 3~5개를 가진다. 작업 공간에 새로운 정보가 들어올 수 없다면 기존 정보를 지우게 된다.”

코드를 읽을 때 논리적인 전개 사이에 복잡한 구조로 불필요한 정보를 작업 공간에 저장하게 하거나 함수의 이름이나 메서드의 이름이 어떤 동작인지 알 수 가 없어 내부 로직을 확인하는 등 이런 과정을 거치게 되면 작업 공간의 초과로 코드를 읽으면서 얻은 정보를 사라지게 합니다.

올바른 추상

추상화 레벨

early return

메서드 매개변수 타입과 변수명

을 활용하여 사고의 흐름을 좋게 만들 수 있습니다.

강의 회고

개발자로 시작하자마자 듣는 문장이 있습니다

a, b,c로 의미없는 변수명을 사용하거나 list1,list2 처럼 숫자가 뒤에 붙는 것은 가독성이 떨어지게 한다.

실제 회사에서 코드를 하다보면 전자는 없다고 하더라도 후자는 종종 보게 됩니다.

후자를 작성하게 되는 이유는 변수명을 고민하지말고 일단 개발을 마무리하고 리팩토링하자는 생각이였지만 새로 들어온 프로젝트로 변경되지 못한 채 남아있는 경우가 많았습니다.

클린 코드가 좋고, 가독성이 좋은 코드가 중요하다는 말은 알고 있지만 제 머리속을 이해시켜주지 못했습니다.

이해가 되지 않은채 가독성이 좋은 코드를 작성하려고 하니 오히려 리팩토링이후 더 알 수 없는 변수명과 메서드 명으로 혼란을 주기만 했었습니다.

혼란스러운 코드를 보고 되돌리고 싶어도 어떤게 가독성이 좋은 코드인지 모르니 다시 리팩토링할 자신이 없었습니다.

강의를 보고 난 후

  1. 사용자에 대한 신뢰가 사라졌습니다.
  2. 추상화가 무엇인지 알게 되었습니다
  3. 사고의 흐름에 대해 고민하게 되었습니다.
  4. 리팩토링 방식의 노하우를 알게 되었습니다.

사용자라는 개념이 무엇인지

MVC 패턴이나 DDD패턴이나 모두 사용하는 측(클라이언트)와 제공하는 측(서버)가 있습니다.

여기서 강사님이 해주신 말이 기억납니다.

사용자를 신뢰하지 않고 확인해야한다.

사용자가 신뢰되는 정보를 준다는 것 자체가 사용자가 누구인지 알고 있는 것이기에 SOLID원칙에서 DIP에 위반된다고 생각이 됩니다.

강의 이후 제가 재정의를 했습니다.

사용자를 신뢰하지 않고 현재 문맥에 맞는 상황을 사용자에게 전달한다.

추상에 대한 생각

추상화에 대해 재정의하는 시간이 되었습니다.

추상은 중요한 것을 보여주고 덜 중요한 것을 덜어내는 것이다.

void 회원_정보이용료_납부(){
  1. 회원이 있는지 확인한다.
  2. 조회된 회원이 이용기간을 확인한다.
    2-1) 이용기간 중이면 아래 로직을 실행한다.
    2-2) 이용기간 만료이면 아래 로직을 실행한다.
  3. 이용기간을 변경한다.
  4. 회원의 정보이용료 납부를 기록한다.
  5. 사용자에게 변경된 정보를 반환한다.  
}

이런 코드가 있다면 결국 필요한 내용은 정보이용료를 납부한다는 것입니다.

여기서 하나의 메서드내에 여러가지 관심사기 있다면 분리를 하거나 추상화 레벨을 높이는 방법을 사용하는 것을 알게되었습니다.

사고의 흐름이 무엇인지

코드를 작성할 때 가독성이 좋다는 게 저에게는 어려운 문제였습니다.

코드 가독성이 나쁘다, 좋다. 메서드명이 명확하다. 그런데 코드 가독성이 나쁘다고 생각하는 이유가 뭘까?

이런 생각이 들었습니다.

회사에 돌아가서 제 코드를 확인해보니 추상화 레벨이 맞지 않았습니다.

void 회원등록(회원생성요청 회원생성정보){
  회원정보 회원정보 = 회원서비스.회원조회(회원생성정보);
  if(회원정보.type = 1){..}
  else if(회원정보.type =2){..}
  else if(회원정보.type =3){..}
  else if(회원정보.type =4){..}
  else {..}
  회원서비스.회원추가서비스확인(회원생성정보);
}

이런 구조로 되어있다보니 제가 메서드명을 추상하여 중요한 정보만 가지고 와도 중간에 추상화 레벨이 다르다보니까 회원 타입에 대한 정보를 읽어와야합니다.

기존 앞뒤 논리에서는 회원 정보에 대한 상태나 필드에 대한 가공이나 사용이 없다가 생기니 회원 정보 클래스에 대한 정보를 단기 기억에 찾아서 넣어야합니다.

이렇게 뇌가 정보를 저장하는 방식과 사고의 흐름을 같이 연결하다보니 가독성이 좋은 코드가 무엇인지 , 추상화 레벨이 어떤 역할을 하는지 조금이라도 알게 되었습니다.

리팩토링 노하우

기존에는 리팩토링을 할때 브런치를 별도로 만들어서 했습니다.

그러다보니 변경지점이 많은 경우 확인하기 어려웠고 기존 코드 로직을 확인하기 위한 과정도 필요했습니다.

이 과정을 거치지 않고 별도 필드나 메서드를 리팩토링할 때 새로운 복사본을 가지고 리팩토링을 하니 더 효율적으로 리팩토링을 할 수 있었습니다.

미션

Day 2

추상과 구체를 나만의 언어로 재정의하기

추상을 하는 이유는 사용자가 구체를 알지 못해도 어떤 기능인지 알 수 있다는 것을 보고 가전제품을 떠올렸습니다.

가전 제품을 구매하면 메뉴얼도 같이 보내줍니다.

저는 가전 제품을 사용하기 위해 메뉴얼을 본 적은 극히 드문 일이였습니다.

이 미션을 보고 이게 추상과 구체라고 생각하게 되었습니다.

사용자는 내부 동작을 정확하게 알지 못하더라도 추상된 버튼을 누르면 알아서 동작하는 것.

그것이 추상과 구체라고 생각하고 미션을 해결하였습니다.

Day 4

코드 리팩토링 미션과 SOLID 재정의 해보는게 미션이였습니다.

코드 리팩토링은 제일 고려한 내용은 다음과 같습니다

  1. 부정어를 메서드로 풀 수 있으면 메서드로 해결한다.
  2. 추상화 레벨을 똑같이 한다.
  3. 관심사를 분리한다.
  4. 복잡한 정보를 주지 않는다.
  5. 사용자를 신뢰하지 않는다.
  6. 오브젝트에게 물어본다.

나만의 언어로 표현하기

객체지향 프로그래밍 세계에서 객체지향 원칙은 질서와 효율적인 코드를 작성을 돕는다는 것을 기반으로 문제를 해결하려고 했습니다.

그러면 역시 가전 제품이다.

기업이 돈을 벌기 위해서 어떠한 방식으로도 사용자의 니즈를 파악하여 물건을 판매해야합니다.

거기서 사용자의 요구를 물건(객체)로 비유하기 적절한 것이 저는 생활 가전이라고 생각했습니다.

생활 가전은 효율적이고 빠른 교체를 기반으로 물건을 만들어낸다고 생각합니다.

그러면 SOLID의 철학과 일치하기에 생활 가전을 기반으로 비유하기로 했습니다.

미션 회고

추상과 구체를 하면서 사용자가 내부 로직을 몰라도 된다.

위 문장을 조금이나마 이해하게 된 한 주가 되었습니다.

기존

기존에는 추상은 말 그대로 메서드를 공통화 하기 위한 메서드명일 뿐이라고 생각했습니다.

중요한 정보만 위로 띄우고 중요하지 않은 것은 지우는 것이 추상화라는 것을 잊고 있었습니다.

그러다보니 메서드 명이나 변수명도 추상이 아니라 단어만 줄이는 거였습니다.

void findMember(){
  그냥 멤버가 아니라 정보이용료 미납을 조회
}

제일 놀란 것은 String타입의 사용이였습니다.

void findMemberByCond(String memberType){...}

저는 유연한 코드를 작성한다고 오히려 String 타입을 주로 사용하고 있었습니다..(충격!!!!)

강의를 보고나서

객체지향 프로그래밍도 현실 세계에서 발생되는 문제를 컴퓨터에 사상하여 해결하기 위한 방식일 뿐이라는 걸 알았습니다.

현실 세계에서 추상은 어떤 것이 있으며, 구체에는 어떤 것이 있는지 생각해보면서 추상화를 잘하면 사용자가 별다른 정보가 없어도 사용할 수 있다는 것을 알게 되었습니다.

메서드 파라미터에 “String”이 이렇게 사용자의 혼란을 주는지 몰랐습니다.

그리고 객체를 전달하는 것이 사용자는 일단 던져주면 알아서 내부에서 사용하는 게 사용자를 편하게 만들게 합니다.

생각해보면 다른 개발자가 변수명에 추상화된 정보를 기입해도 String 타입이 있다면 어떤걸 전달해달라는 건지 확인하기 위해 서비스 계층부터 데이터 접속계층까지 들어가는 경우가 많았습니다.

사용자에게는 광범위한 범위를 제공하는 것이 혼란을 준다는 것을 알게되었습니다.

출처

인프런 워밍업 클럽

인프런 워밍업 클럽 스터디 3기 - 백엔드 클린코드, 테스트 코드(Java, Spring Boot)

강의 링크

Readable Code: 읽기 좋은 코드를 작성하는 사고법

Practical Testing: 실용적인 테스트 가이드

댓글남기기