강의 정리/클린 코더스 강의

클린 코더스 강의 - OOP(Object-Oriented Programming) part

i-hwin 2025. 5. 31. 16:42

개발을 진행하다 보니 클린 코드의 중요성을 절실히 깨닫게 되었다. 직접 작성한 코드임에도 복잡해서 알아보지 못하는 경우가 있었고, 기능 추가를 하기 위해서 생각했던 시간보다 많이 들었고, 팀원의 코드를 이어서 작성해야 할 때 시간이 오래 걸리는 등 개발 효율을 떨어트리는 많은 상황을 만났기 때문이다.

 

클린 코더스 강의를 통해 깨끗한 코드의 필요성, 절차적 프로그래밍과 객체지향 프로그래밍의 차이, 그리고 실제로 코드 품질을 높이는 방법까지 정리해보고자 한다.

 

깨끗한 코드란 무엇인가?

깨끗한 코드란 읽기 쉽고, 유지보수와 확장이 용이하며, 버그가 적은 코드를 의미한다. 여러 개발자가 협업하는 환경에서는 내가 작성한 코드를 다른 사람이 받아서 개발하는 경우가 대부분이기에 읽기 쉬워야 한다. 특히 중요하며, 코드 리뷰나 리팩토링 시에도 큰 도움이 된다.

 

왜 클린 코드가 필요한가?

  • 유지보수와 확장성
    코드가 복잡해질수록 유지보수가 어려워지고, 새로운 기능을 추가할 때마다 기존 코드를 수정해야 할 일이 많아진다. 이를 위해서는 '읽기 쉬운 코드' 중요하다.
  • 협업 효율성
    여러 명이 함께 개발할 때, 누구나 쉽게 이해할 수 있는 코드는 커뮤니케이션 비용을 낮춘다.
  • 버그 감소
    명확하고 일관성 있는 구조는 실수나 오류를 줄여준다.

 

Procedeur(절차적) vs OOP(객체지향적)

 

단순한 시스템, 한번만 쓰는 이벤트 등은 쉬운 절차지향으로 하는 것이 낫다.

하지만 복잡하거나 요구사항 변화가 발생할 시스템은 객체지향으로 해야한다. 데이터의 변경이 해당 객체로만 제한되고 다른 객체에 영향을 미치지 않기 때문이다.

 

(1) 절차적 프로그래밍의 한계

절차적 프로그래밍은 단순한 프로젝트에서는 잘 동작하지만, 규모가 커질수록 다음과 같은 문제가 발생합니다.

  • 코드 중복과 스파게티 코드
    기능이 추가될수록 코드가 얽히고 중복이 발생해 관리에 문제가 생김.
  • 변경에 취약
    요구사항이 바뀌면 여러 곳을 동시에 수정해야 하며, 실수로 인한 버그가 생길 가능성이 높아진다.
  • 확장성 부족
    새로운 기능 추가 시 기존 코드를 많이 수정해야 하는 구조적 한계가 있다.

위와 같은 한계가 있기에 객체지향 프로그래밍으로 설계해야한다.

 

(2) 객체지향 프로그래밍의 장점

  • 캡슐화와 추상화
    데이터와 기능을 객체 단위로 묶어 복잡성을 줄입니다.
  • 다형성과 확장성
    상속과 다형성을 통해 코드 재사용이 용이하고, 새로운 기능 추가가 상대적으로 쉬워집니다.
  • 책임 분리
    각 객체가 자신의 역할에 집중할 수 있어 시스템 전체 구조가 명확해집니다.

(3) 객체 지향 설계 과정

1st. 기능을 제공할 객체 후보 선별

- 내부에서 필요한 데이터 선별

- 클래스 다이어그램

- 정적 설계

 

2nd. 객체 간 메시지 흐름 연결

- 커뮤니케이션 다이어그램

- 시퀀스 다이어그램

- 동적 설계

 

3rd. 1st, 2nd 반복

-  구조와 흐름을 반복적으로 검토하며 설계를 구체화

 

(4) 실무에서 깨끗한 코드를 작성하는 방법

  • 명확한 네이밍
    변수, 함수, 클래스 이름을 직관적으로 짓습니다.
  • 함수와 클래스의 크기 최소화
    한 함수(메서드)는 한 가지 일만 하도록 설계합니다.
  • 주석보다는 코드 자체로 설명
    불필요한 주석보다는 코드 자체가 이해하기 쉽도록 작성합니다.
  • 리팩토링 습관화
    기능 추가나 버그 수정 시, 기존 코드를 꾸준히 개선합니다.

 

(5) 객체지향의 다형성

객체지향의 장점을 말할 때 흔히재사용성을 꼽는다. 하지만 재사용성의 본질이 무엇인지 한 스텝 더 들어가보면, 단순히 상속을 통한 부모-자식 간의 메서드와 변수 공유만이 전부는 아니다.

클린 코더스 강의에서는상속이 재사용성의 핵심이 아니며, 인터페이스를 활용한 설계가 진짜 재사용성이라고 강조한다.
인터페이스를 사용하면 여러 클래스를 쉽게 갈아 끼울 수 있고, 외부에서는 어떤 구현체가 들어오든 동일한 방식으로 사용할 수 있다.
, 상속은 구현의 재사용에 불과하지만, 인터페이스는역할구현을 분리하여, 실제로 코드의 교체와 확장이 훨씬 쉬워진다.

예를 들어,LogCollector라는 인터페이스를 두고, 파일에서 로그를 수집하는 구현체와 네트워크에서 로그를 수집하는 구현체를 각각 만들 수 있다.
이렇게 하면 로그 수집 방식이 바뀌어도 클라이언트 코드는 전혀 영향을 받지 않는다.

 

 

마지막으로, 강의를 시작하면서 백명선님께서 하신 말씀이 깊이 와닿았다.

시스템이 이해하고 읽는 코드는 누구나 작성할 수 있지만, 인간이 이해할 수 있는 코드는 잘 훈련된 SW 엔지니어만이 작성할 수 있다.”

앞으로 나는 단순히 돌아가는 코드에 만족하지 않고사람이 읽기 쉬운 코드, 협업하기 좋고 유지보수하기 쉬운 코드를 쓰는 개발자가 되기 위해 꾸준히 연습할 것이다.
공부하고 고민하고 훈련하는 과정을 통해 안정성이 높은 개발을 위한 단단한 기반을 쌓아나가고 싶다.