객체지향에 대해서 처음 들은 건 코틀린 독학을 시작했을 때였습니다. 코틀린이 객체지향 프로그래밍 언어라는 설명과 함께 객체지향 프로그래밍에 대해 간략한 소개를 읽었던 기억이 납니다. 객체를 지향하는 프로그래밍으로, 여러 객체를 조합하여 프로그램을 완성시키는 방법으로 이해했습니다. 그러면서, 클래스와 프로퍼티, 메서드에 대해 학습하고 객체가 무엇인지, 인스턴스가 무엇인지 알게 되었던 것 같습니다. 그 이후로, 자바와 파이썬 언어를 학습하면서 점점 더 많은 객체지향 언어를 다루다 보니 객체에 대해서는 조금이나마 감을 잡을 수 있었습니다. 하지만 객체지향 언어가 아닌 언어를 다뤄본 경험이 없어 객체지향 프로그래밍만의 장점이나 특징들에 대해서는 알기가 어려웠습니다.
객체지향 프로그래밍의 장점은 단순성, 유연성, 변경 가능성이라고 배웠습니다. 아이러니하게도, 객체지향 프로그래밍이 무엇인지 제대로 이해하기 전에 그 장점들을 잘 사용할 수 있게 하는 원칙과 구조에 대해 먼저 학습했습니다. SOLID 원칙, Clean Architecture, 의존성 주입에 대해 공부할 때 추상화와 인터페이스의 중요성에 대해 깨달을 수 있었습니다. 이전까지는 굳이 이렇게까지 해야 하나? 싶었던 부분들이 이해가 가기 시작했던 순간이었습니다.
그 후, [객체지향의 사실과 오해] 책을 읽으면서 객체지향이 정확히 뭔지, 객체지향 프로그래밍에서 주의해야 할 점이 뭔지 알게 되었습니다. 정말 좋은 책이라 작가님께 감사해하며 읽었습니다. 책 구매는 무조건 추천입니다. 비전공자도 읽을 수 있게 쉽게 서술되어 있으며, 개발 경험이 있다면 좀 더 깊게 이해할 수 있는 책입니다. 머릿속에 추상적으로 떠돌아다녔던 개념들을 읽기 쉬운 이야기로 정리해 주십니다.
이 글은 이전에 읽었던 [객체지향의 사실과 오해] 책을 다시 읽으면서 공부한 내용입니다.
객체 지향 프로그래밍 (Object-Oriented Programming)
객체 지향 프로그래밍(OOP)은 객체를 중심으로 시스템을 설계하고 구현하는 프로그래밍 패러다임입니다. 객체는 상태와 행위를 가진 독립적인 실체로, 서로 협력하여 시스템의 기능을 수행합니다. 이를 통해 유연하고 확장 가능한 소프트웨어를 구축할 수 있습니다.
객체 지향의 핵심 원칙
- 자율적인 객체: 객체는 스스로 상태를 관리하며, 자신이 제공하는 행위를 통해 상태를 변경합니다.
- 협력과 역할: 시스템의 기능은 객체 간의 협력으로 이루어지며, 객체는 역할과 책임을 기반으로 협력에 참여합니다.
- 메시지와 메서드: 객체는 메시지를 통해 요청을 받고, 요청을 처리하는 메서드를 자율적으로 선택합니다.
객체 지향의 지향점
- 단순성: 불필요한 복잡성을 제거하고 명료하게 설계합니다.
- 유연성: 변경에 잘 대응할 수 있는 구조를 설계합니다.
- 변경 가능성: 유지보수와 확장이 용이하도록 설계합니다.
객체 지향의 주요 개념
1. 메시지
- 요청과 요청에 포함된 정보입니다.
- 무엇을(What)의 관점에서 요청합니다.
2. 메서드
- 메시지를 처리하는 구체적인 방법입니다.
- 어떻게(How)의 관점에서 응답합니다.
3. 책임
- 요청과 응답을 하는 임무입니다.
4. 역할
- 객체가 협력 과정에서 맡는 책임의 집합입니다.
- 같은 역할을 맡은 객체는 서로 대체될 수 있습니다.
5. 협력
- 객체들이 연쇄적으로 메시지를 주고받으며 역할과 책임을 수행하는 과정입니다.
주요 원칙
캡슐화
객체는 자신의 상태를 외부로부터 숨기고, 행동(메서드)을 통해서만 상태에 접근할 수 있도록 합니다.
- 장점: 객체의 자율성 유지, 변경에 강한 구조 제공
인터페이스
두 개체가 만나는 경계에서 상호작용을 가능하게 해주는 방법이나 장치를 말합니다. 객체 지향 프로그래밍에서는 주로 클래스가 제공하는 메서드 집합을 의미합니다.
좋은 인터페이스의 조건
구체적인 구현보다 행동의 약속(계약)을 중심으로 설계
→ 객체의 자율성을 보장합니다.
외부에서 접근할 필요가 없는 기능은 감춥니다.
→ 변경 가능성을 줄여 안정성을 높입니다.
외부에 공개된 인터페이스와 내부 구현을 명확히 구분합니다.
→ 객체의 자율성을 보장하고, 변경에도 안정적인 구조를 제공합니다.
추상화
복잡한 시스템에서 중요한 부분만 표현하고 불필요한 세부 사항은 생략합니다.
- 목적: 복잡도 감소와 이해도 향상
타입 (Type)
객체가 어떤 타입에 속하는지를 결정하는 것은 객체가 수행할 수 있는 행동입니다.
타입의 장점
객체의 유연성을 높이고 다형성을 지원합니다. 동일한 타입을 공유하는 객체들은 서로 다른 내부 구현을 가질 수 있지만, 같은 방식으로 사용할 수 있습니다.
클래스 (Class)
클래스는 타입을 구현하기 위한 도구입니다. 객체 지향 프로그래밍에서 클래스는 객체를 생성하기 위한 템플릿 역할을 하며, 상태와 행동을 정의합니다.
일반화(슈퍼타입)
여러 타입의 공통점을 추출하여 추상화합니다.
예: "동물"이라는 슈퍼타입은 "고양이"와 "개"의 공통 행동(걷기, 먹기 등)을 정의할 수 있습니다.
특수화(서브타입)
슈퍼타입보다 더 많은 행동이나 속성을 가지는 타입입니다. 서브타입은 슈퍼타입을 대체할 수 있어야 하며(리스코프 치환 원칙), 이는 상속 설계의 핵심입니다.
상속
특정 클래스의 속성과 메서드를 하위 클래스에 물려주는 메커니즘입니다.
- 유형:
- 서브타이핑(인터페이스 상속): 하위 클래스가 상위 클래스를 대체할 수 있는 경우
- 목적: 설계의 유연성을 제공
- 서브클래싱(구현 상속): 하위 클래스가 상위 클래스를 대체할 수 없는 경우
- 목적: 코드 재사용과 중복 제거
- 서브타이핑(인터페이스 상속): 하위 클래스가 상위 클래스를 대체할 수 있는 경우
설계
책임 주도 설계
- 어떤 메시지가 필요한지 결정합니다.
- 메시지에 적합한 객체를 선택합니다.
구조 설계와 기능 설계
구조를 안정적으로 설계하고 그 후에 기능을 설계합니다.
- 구조 설계: 시스템의 형태와 구성 요소를 정의
- 기능 설계: 시스템이 제공하는 주요 기능을 설계
도메인 모델과 유스케이스
유스케이스의 기능을 도메인 모델을 기반으로 한 객체의 책임으로 나누고 협력 관계를 설계합니다.
도메인 모델
도메인과 관련된 핵심 개념과 관계를 추상화하여 표현한 모델입니다. 구조 설계에 사용됩니다.
유스케이스
시스템이 다양한 조건에서 어떻게 동작하는지 이야기 형식으로 서술합니다. 기능 설계에 사용됩니다
객체 지향 프로그래밍은 단순히 코드를 작성하는 것이 아니라, 객체 간의 협력과 책임을 명확히 정의하는 과정입니다. 이를 통해 복잡한 문제를 해결하고, 확장 가능하고 유지보수하기 쉬운 소프트웨어를 구축할 수 있습니다.
'개발공부 > 한눈에 보기 👀' 카테고리의 다른 글
자바, 코틀린, 파이썬, C++ 한눈에 비교하기 (3) | 2025.01.17 |
---|---|
프로그래밍 관련 용어 정리 (2) | 2024.12.26 |