개발 지식

[개발 지식] 좋은 객체 지향 프로그램과 좋은 사람의 공통점

진철 2024. 4. 5. 20:53
728x90
반응형
들어가며(주제와 관련이 없는 아이스 브레이킹과 같은 이야기니, 넘어가셔도 좋습니다.)

스프링을 처음 접했던 시기는 올해 1월달이었다.

그 당시에는 누군가의 강의를 듣는 것보다는 책으로 접하는 것이 다 낫겠다라고 판단하여, O'Reilly사의 책으로 학습을 진행했었다.

하지만, 저자가 외국인 점도 그렇고 코드와 글로만을 통해서 온전히 내 것으로 만드는 것은 그렇게 쉽지 않은 일이었다. (더군다나, REST ful API와 같이 기본적인 백엔드 지식도 제대로 모르는 상황이었으니 말이다.)

책과 블로그들을 통해 혼자 간단한 게시판을 만들며, 전전긍긍하다가 "그래도 이정도면 1인분은 하지 않을까? 기본적인 내용은 안 것 같은데?"라는 생각이 들 때쯤 내 위치가 어느 정도인지 궁금해서 지난 3월달부터 김영한님의 강의를 듣게 되었다.

 

결론은 아직 수행이 더 필요하다는 것.

그렇게 다시 개념을 내 것으로 만들기 위해 김영한님의 강의를 열심히 수강하였고 그 학습한 내용을 정리하여 작성하려고 한다.

수강을 완료하고 1달 후에 블로그를 작성하는 이유는 다음과 같다.

김영한님의 강의는 무엇보다 저작권에 민감한 내용들이 많기 때문에 강의 내용을 그대로 작성하면 문제가 발생한다. 

따라서, 강의 내용과 겹치지 않게 최대한 나만의 언어로 작성해야한다. (참고로 예시 코드는 혹시라도 문제가 될까봐 아예 작성하지 않을 예정이다.)

나만의 언어로 작성하기 위해서는 완벽, 혹은 그에 가까운 이해도가 필요하다. 

이 과정에서 시간이 꽤나 오래 걸린 것 같다.

물론 지금도 아직 햇병아리 수준이지만, 이쁘게 봐주셨으면 좋겠습니다.(뿌잉뿌잉 ㅋ)

 

객체 지향 세계는 현실 세계와 같은 성질을 가진다.

필자가 대학교 2학년일 때, "자바 프로그래밍"이라는 수업에서 지겹도록 들은 말이 있다.

그것은 바로, 현실 세계와 객체 지향 세계은 동일하다는 점.

처음에는 "이게 뭔 소리지?"하고 웃음을 지었다.

객체 지향 세계는 디지털 세계를 일컫는 말인데, 디지몬도 아니고 어떻게 디지털 세상과 현실 세상이 같다는 건가라는 생각이 먼저 떠올랐던 것 같다.

 

사실 교수님께서는 이런 의미로 말씀하신 것이 아니다. (당연하지 ㅋㅋ)

객체라는 개념 자체는 사물이나 동물 등 물체 하나하나를 의미한다.

따라서, 현실 세계에는 수 많은 객체들이 상호작용을 하며 살아가고 있고 이 모습은 객체 지향 프로그래밍에서도 동일하다.

자바 코드를 통해 생성된 수 많은 객체들이 상호작용을 하면서 하나의 프로그램을 완성시킨다.

현실 세계와 객체 지향 세계는 방식은 다르지만 목적은 모두 같은 것을 알 수가 있다.

 

"다형성", 객체 지향 프로그램의 꽃

객체는 다형성이라는 성질을 가지고 있다.

다형성이란 영어로 하면 Polymorphism, 한자로 하면 多形性로 다양한 형태를 가질 수 있다는 성질을 의미한다.

즉, 하나의 객체가 여러 가지 타입을 가질 수 있는 것이다.

이해를 좀 더 돋구기 위해 자동차를 통해서 비유를 해보자.

앞에 세단, SUV, 경차 총 세 종류의 자동차가 있다고 하자.

이 세 가지는 모두 "자동차"이며, 만약 면허가 있다면 어느 것을 타던지 큰 문제가 없을 것이다.

객체(자동차)가 다양한 형태(세단, SUV, 경차)로 존재하는 것을 느꼈나? (멋져)

이를 다형성이라고 한다.

 

다형성을 강조하는 이유

앞서 언급한 자동차 예시와 이어지는 내용이다.

차량의 종류가 다르더라도 자동차라는 근간은 변하지 않기 때문에 종류가 변했다는 사실 하나로 운전자에게 영향을 끼치지 않는다.

그리고 어떤 차량의 종류든지 운전을 할 수 있으니 "유연하다"라고 할 수 있다.

이는 역할(자동차)과 기능(세단, SUV, 경차)으로 구분했기 때문에 가능한 일이다.

더군다나, 운전자는 차량의 엔진이 어떠한 원리로 작동하는지, 베어링은 어떻게 구성되었는지 등 차량의 내부 설계를 모르더라도 운전을 하는 데에는 전혀 영향을 받지 않는다.

즉, "유연하다"는 약방의 감초와 같은 장점은 서비스에서 클라이언트에게 영향을 주지 않고 새로운 기능을 제공할 수 있다는 가능성을 준다.

 

SOLID, 좋은 객체 지향 프로그램의 기반

이제 위의 비유를 프로그래밍에 적용시켜보자.

서비스에서 클라이언트에게 영향을 주지 않고 새로운 기능을 제공할 수 있도록 우리는 유연한 프로그램을 만들어야한다.

따라서, 객체를 설계할 때 인터페이스를 통해 역할을 먼저 부여하고 그 역할을 수행하는 구현 객체를 부여해야한다.

그리고 개발자는 API 등과 같은 호출에서 변화가 있더라도 최대한 인터페이스 자체가 흔들리지 않게 설계하는 것이 매우 중요하다. 

새로운 차종을 출시했지만, 자동차 기능을 제대로 수행하지 못한다면 과연 이는 자동차라고 할 수 있겠는가?

이와 같은 문제를 일으키지 않는다면 그것은 좋은 프로그램이지 않을까?

따라서, 선대 개발자들은 SOLID 원칙이라는 것을 만들었는데, 이는 좋은 객체 지향 설계의 기반이 되는 원칙이다.

SOLID는 다섯 가지 특징들의 앞 부분을 딴 것이며, 각 의미는 아래와 같다.

 

S(SRP : 단일 책임 원칙) - 하나의 클래스는 하나의 책임만 가져야 한다. 변경이 있을 때, 파급이 적다면 해당 원칙을 잘 지킨 것이다.

 

O(OCP : 개발 폐쇄 원칙) - 확장하는 것은 상관없으나, 변경하는 것은 닫혀있어야 한다. 근데, 해당 정의는 상당히 모순적인 생각을 들게 한다. 시스템을 확장하려면 코드를 변경해야하는 것은 당연한 것인데 말이다. 여기서의 변경은 코드 자체를 변경한다는 것이 아니다. 시스템을 확장하면 그에 걸맞는 새로운 기능이 추가되기 마련인데, 개발자가 직접 코드를 작성하지 않고 간단한 방법으로 객체 간의 연관관계를 수정할 수 있어야함을 의미한다.

 

L(LSP : 리스코프 치환 원칙) - 이름에서 알 수 있듯이, 리스코프라는 개발자가 내세웠다. 객체 지향 프로그램에서는 인터페이스와 그에 대한 구현체가 있는데, 이 구현체의 기능은 인터페이스의 규약을 따라야한다는 것이다. 예를 들어서 자동차에서의 엑셀은 앞으로 가야한다는 규정이 있다. 하지만, 구현체가 엑셀을 뒤로 가게 생성되었다면 이는 인터페이스의 규약을 어긴 것이다.

 

I(ISP : 인터페이스 분리 원칙) - 하나의 범용 인터페이스보다는 여러 개의 인터페이스가 낫다는 것을 의미한다. 차량에 있어서 운전과 정비 부분을 통합하여 관리하는 것보다 운전과 정비로 분리하여 관리하는 것이 더 효율적인 것처럼 말이다.

 

D(DIP : 의존관계 역전 원칙) - 객체가 존재하는 것만으로는 프로그램을 완성할 수가 없다. 현실 세계에서 여러 객체들이 상호작용을 통해 세상이 움직이듯이 프로그램 내에서도 객체들의 상호작용이 필요하다. 의존관계는 객체들의 상호작용이라고 봐도 무방하다. 따라서, 상호작용을 개발자가 지정해주어야 한다. 이 때, 구체화에 의존하지 않고 추상화에 의존해야한다는 것이다. 구현 클래스 그 자체에 집중하는 것보다는 그보다 더 넓은 개념인 인터페이스에 집중해야한다. 즉, 기능에 집중하지 말고 역할에 신경쓰라는 것이다. 프로그램에서는 클라이언트가 인터페이스에 의존해야 비로소 유연해질 수 있다.

 

공연으로 알아보는 좋은 객체 프로그래밍

이는 객체 지향 프로그래밍에서 핵심이라고도 할 수 있다.

우리가 공연을 계획한다고 해보자.

개발자는 공연 기획자와 같이 특정 기능(배역)에 대한 인터페이스를 설계하고, 그에 맞는 구현체(배우)를 선택하여 일을 진행할 것이다.

그렇다면 나머지 무대 장치나 의상, 소품 등은 기획자가 맡으면 될 것이고 배우들은 배역에만 집중할 수 있어서 유연성과 확장성을 극대화할 수 있다.

따라서 인터페이스를 먼저 정의하고 그 이후에 구현체를 개발하는 방식이 좋고 실제로도 많이 권장되는 방식이다.

이는 변경 가능성이 있는 부분을 인터페이스 뒤에 숨겨 놓고, 필요에 따라 구현체를 교체할 수 있도록 함으로써 유연성을 제공한다.

아직 정해지지 않은 부분(DB 선택 등)을 우선 임시로 두고, 필요에 따라서 쉽게 교체할 수 있는 유연한 구조를 만들 수 있다.

 

좋은 객체 지향 프로그램과 좋은 사람의 공통점

조금 억지일 수도 있지만 필자는 좋은 객체 지향 프로그램을 학습하면서 좋은 사람과도 꽤나 비슷한 점이 있다고 생각했다.

 

먼저, 모듈화와 책임 분배를 느꼈다.

좋은 객체 지향 프로그램은 모듈화되어 있고, 각 모듈은 잘 정의된 책임을 가지고 있다.

비슷하게, 좋은 사람은 자신의 역할과 책임을 이해하고 그에 따라 행동한다.


그리고 유연성과 적응성이 뛰어나다는 점이다.

좋은 객체 지향 프로그램은 변경에 대한 유연성을 가지고 있어서 새로운 요구사항에 쉽게 대응할 수 있다.

비슷하게, 좋은 사람은 새로운 상황에 적응하고 필요에 따라 유연하게 행동할 수 있다.


그리고 의사 소통과 협업에 강하다.

좋은 객체 지향 프로그램은 객체 간의 의사 소통이 원활하고 협업이 잘 이루어진다.

비슷하게, 좋은 사람은 타인과의 의사 소통을 중요시하고 협업을 통해 함께 일하는 데에 적극적이다.


재사용성과 확장성이 좋다.

좋은 객체 지향 프로그램은 코드의 재사용성과 확장성을 고려하여 설계된다.

비슷하게, 좋은 사람은 자신의 경험과 지식을 재사용하고 발전시켜 나가며 계속해서 성장하려고 노력한다.


품질과 규모에서 반비례가 일어나지 않는다.

좋은 객체 지향 프로그램은 코드의 품질을 유지하면서도 큰 규모의 시스템을 구축할 수 있다.

비슷하게, 좋은 사람은 자신의 가치와 원칙을 유지하면서도 큰 목표를 향해 나아갈 수 있다.


그리고 결론적으로 좋은 객체 지향 프로그램과 좋은 사람은 더 나은 결과물을 만들어내고 성공적으로 성장할 수 있다는 공통점을 가지고 있다.

 

마치며

오늘은 이렇게 좋은 객체 지향 프로그램이 무엇이고 좋은 사람과 어떤 점이 닮아있는지에 대해서 알아보았다.

조금 내용이 길고 지루할 수도 있지만 그래도 도움이 많이 되었으면 좋겠다.

감사합니다.

728x90
반응형