inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 스터디] 추상과 객체 지향의 구체화

hgh1472
1

인프런 ‘Readable Code: 읽기 좋은 코드를 작성하는 사고법’을 수강한 후, 작성한 내용입니다.

📌 1주차 기간 강의

섹션 2. 추상

코드를 잘 짠다는 것은?

개발자라면 코드를 잘 짜기 위해 노력한다. ‘코드를 잘 짠다’라는 것은 무엇일까?

코드를 잘 짠다는 것은 이해하기 쉬운 코드, 즉 ‘읽기 좋은 코드’라는 것에 동의하지 않는 사람은 없을 것이다.

내가 짠 코드를 읽는 대상은 결국 나와 동료이다. 미래의 나와 동료를 위해 매 순간 읽기 좋은 코드를 작성하려고 노력해보자.

클린 코드와 리팩토링의 가장 좋은 예시는 테스트 코드 생성 사이클로 볼 수 있다.

클린 코드를 추구하는 이유

그런데 클린 코드를 추구하는 이유는 뭘까?

코드가 잘 읽힌다 ⇒ 이해가 잘 된다 ⇒ 유지보수하기 수월하다 ⇒ 시간과 자원이 절약된다!

즉, 클린 코드는 우리의 시간과 자원을 절약해준다.

클린 코드, 그리고 추상과 구체

추상은 클린 코드를 관통하는 주제이다. 그렇다면 추상이란 뭘까?

추상 : 중요한 정보는 가려내어 남기고, 덜 중요한 정보는 생략하여 버린다.

추상의 반대편은 구체라고 볼 수 있다. 하나의 예시를 들어보자.

답변 1과 답변 2는 같은 의미를 나타낸다. 그런데 표현은 다르다. 답변 2는 구체적인 사실이고 답변 1은 추상화된 문장이라고 할 수 있다.

구체에서 추상으로 갈수록 정보는 함축되어 제거되고, 추상에서 구체로 갈수록 생략된 정보를 유추하고 재현한다.

이를 개발자답게 컴퓨터 과학에 적용해보자.

int는 4 byte이고, char는 1 byte이다. 같은 byte로 이루어지지만, 데이터를 어떻게 읽는지에 따라 달라진다. 즉, 데이터 개념에도 추상화가 존재하는 것이다!

잠깐 프로그램의 정의에 대해 생각해보자. 프로그램은 다음과 같이 말할 수 있다.

프로그램 = 데이터 + 코드

위의 예시를 통해 데이터 개념에 추상화가 존재함을 알 수 있었다. 당연히 코드에도 추상화가 존재한다. 또한 데이터 + 코드에도 추상화가 존재한다.

흔히 고수준/저수준 언어 라는 용어를 들어봤을 것이다. 고수준과 저수준이 나뉘는 이유는 추상화에 대한 수준을 나타내기 때문이다. 잊고 있을 수 있지만, 컴퓨터는 0과 1밖에 모른다!

적절한 추상화는 복잡한 데이터와 복잡한 로직을 단순화하여 이해하기 쉽게 한다!

만약 어느 도시에서 예약을 선택이라고 한다고 가정해보자. 그렇다면 답변 1은 다음과 같이 바뀔 것이다.

이 말을 들으면 무슨 말인가 싶다. 말을 통해 유추하거나 재현하기 쉽지 않다. 단순히 말이 안된다고 생각할 수 있지만 이유에 대해 따져보자.

잘못된 추상화가 야기하는 사이드 이펙트는 상당히 크다!

적절한 추상화란 해당 도메인의 문맥 안에서 정말 중요한 핵심 개념만 남겨서 표현하는 것이다.

이름 짓기

이름을 짓는다는 행위는, 추상적 사고를 기반으로 한다.

좋은 이름을 짓기 위해 노력하자!

메서드 추상화

메서드 이름으로 구체적인 내용을 추상화할 수 있어야 한다.

잘 쓰여진 코드라면, 한 메서드의 주제는 반드시 하나다!

그런데 내용이 다음과 같다고 해보자.

추상화된 내용을 보고 구체적인 내용의 유추가 어렵다. 의미를 담을 수 있는 더 작은 단위로 쪼개야 한다.

메서드 작성

메서드명

파라미터

어떤 재료가 필요한지 알려주는 역할이다. 외부 세계한테 필요한 재료를 요구한다.

반환타입

코드의 줄 수가 많아서 추상화하는 것이 아니다! 같은 라인 수를 가지더라도 추상화할 수 있다.

추상화 레벨

메서드를 추출한다 ⇒ 외부 세계와 내부 세계를 나누고, 추상화 레벨이 나뉜다.

하나의 세계 안에서는, 추상화 레벨이 동등해야 한다!

  1. 게임 시작 멘트 출력

  2. 게임 초기화

  3. 게임 보드 보여주기

  4. 게임 상태가 1이면

    • 게임 종료 메시지 출력

1, 2, 3, 4를 쭉 읽다보면 4에서 멈칫하게 된다. 게임 상태 = 1이라는 것의 의미에 대해서 의문이 생기게 된다. 즉, 읽는 사람이 해석을 하게 만든다. 따라서 동등한 추상화 레벨을 맞춰야 한다.

  1. 게임 시작 멘트 출력

  2. 게임 초기화

  3. 게임 보드 보여주기

  4. 게임을 이겼다면,

    1. 게임 종료 메시지 출력

전보다 훨씬 읽기 수월하다.

메서드로 추출한다는 것은 로직이 복잡하거나 의미를 부여할 수 있어서도 맞지만, 추상화 레벨을 동등하게 맞춤으로써 읽는 사람으로 하여금 자연스럽게 이해할 수 있게 한다.

매직 넘버, 매직 스트링

섹션 3. 논리, 사고의 흐름

인지적 경제성

코드를 작성할 때 인지적 경제성을 추구하도록 작성해보자!

💡 인지적 경제성?

- 최소의 인지적 노력으로 최대의 정보 제공

- 한 번에 한 가지 일

즉, 최소한의 인지만 가져가서 최대의 효율을 내보자라는 뜻!

코드를 읽는 사람의 메모리를 효과적으로 쓸 수 있도록 해서 읽기 좋은 코드를 작성하자.

Early Return

즉, 앞 선 정보들을 모두 기억하고 있어야 함!

Early Return을 이용하자!

사고의 depth 줄이기

중첩 분기문, 중첩 반복문

메서드 추출을 통해 중첩 분기문/반복문을 없애자! 그렇다고 무조건 1 depth로 만들라는 것은 아니다.

사용할 변수는 가깝게 선언하기

공백 라인도 의미를 가진다!

부정어를 대하는 자세

해피 케이스와 예외 처리

섹션 4. 객체 지향 패러다임

추상의 관점으로 바라보는 객체 지향

객체란?

관심사의 분리

객체 설계

도메인 지식은 만드는 것이 아니라 발견하는 것!

SRP (단일 책임 원칙)

하나의 클래스가 하나의 책임만 갖도록 설계해라!

객체를 하나의 변경 지점, 하나의 책임으로만 가지도록 설계하자!

책임을 보는 눈을 기르자!

OCP (개방-폐쇄 원칙)

LSP (리스코프 치환 원칙)

ISP (인터페이스 분리 원칙)

DIP (의존성 역전 원칙)

💡스프링에서의 DI, IoC

DI = Dependency Injection

- 필요한 의존성을 직접 생성하는 것이 아니라, 외부에서 주입받는다.

- 제 3자(스프링 컨텍스트)가 런타임 시점에 의존성을 주입해준다.

IoC = Inversion of Control

- 프로그램의 흐름을 프레임워크가 담당

- 빈 생성, 의존성 주입, 생명주기 관리를 스프링 컨테이너가 해준다. 

섹션 5. 객체 지향 적용하기

상속과 조합

Value Object

VO vs Entity

일급 컬렉션

Enum의 특성과 활용

숨겨져 있는 도메인 개념 도출하기


 

📌 1주차 수강 후 느낀점

강의 제목들을 보면, 사실 개발자라면 다 한번씩 들어봤을 내용이다. SOLID 원칙, 추상화, VO, Enum 등등 누군가 질문하면 그럴듯한 답변을 할 수 있는 주제다. 그런데 ‘이 내용들을 깊이 있게 이해하고 있을까?’ 라는 질문에는 아니었던 것 같다.

이러한 개념들을 직접 코드 레벨에 적용하며 개선하는 과정에서 배울 점이 많았다. 내가 알고 있던 깊이는 상당히 얄팍했다. 가끔 헷갈리면 검색해서 ‘아 대충 이런내용이었지.’하고 금방 닫곤 했는데, 이번 기회에 직접 경험해보며 내 지식들을 구체화시킬 수 있었다. 개발자가 가볍게 여기고 넘어갈 수 있는 주제들에 대해 다시 생각하며, 기본기의 중요성을 알 수 있었다! 그리고, 기존에 프로젝트하며 고민했던 지점이 있었다. 추상화를 할 때 ‘같은 라인 수를 가져도 굳이 해아하나?’ 생각했었는데, 나한테 해답이 되는 1주차였던 것 같다!! 전부터 ‘한 번 들어야지!’했던 강의인데 워밍업 스터디를 계기로 수강하길 잘한 것 같다🙂


 

📌 1주차 미션

Day 2 : 추상과 구체 예시 생각해보기

뭔가 추상화를 실생활에 생각해본 적은 없었는데, 느낌이 새로웠다. 되게 개발스러운 단어라고만 생각했는데 추상은 우리의 삶에도 가까이 적용되는 단어라는 것을 느꼈다.

농구에서 슛을 한다고 해보자. 이때 무릎을 구부리고, 팔꿈치를 올리고, 무릎을 다시 피고, 팔꿈치를 다시 피고, 손목을 피며 공을 던진다. 위 여러 과정들이 ‘슛’으로 추상화된다. 우리 삶의 추상화는 상당히 자주 쓰인다!

Day 4 : [섹션 3. 논리, 사고의 흐름] 내용을 중심으로 리팩토링하기

이전에는 코드를 리팩토링하면, 되게 느낌적으로 다가갔던 것 같다. ‘뭔가 이게 나은 것 같긴한데..’하며 접근하거나 단순히 코드 라인을 줄이는 등 이유와 근거가 빈약했다. 하지만 Day 4 미션을 통해 리팩토링의 이유와 근거를 통해 리팩토링을 진행해보았다.

위 과정을 통해 미션에서 주어진 코드를 읽기 좋게 개선하였다. 읽으면서 사고의 흐름이 멈칫하거나 꼬일 수 있던 코드를 바로 읽어나갈 수 있게 작성하려고 노력했다.

강의를 들으면서 내가 납득됐던 내용에 대해 직접 리팩토링에 적용하여 ‘읽기 좋은 코드’를 만들어 나갈 수 있었다. 단순히 불필요한 작업을 없애는 것만이 리팩토링이 아니라, ‘읽기 좋은 코드’를 만드는 것도 중요한 리팩토링이라는 것을 깨달았다!

백엔드 추상 객체지향

답변 0