나는 이전까지 객체지향프로그래밍에 대해서 방법론적, 기술적으로 받아들이기 위해 노력했는데, 더 복잡한 프로그램과 문제를 코드로 해결하기 위한 첼린지를 마주하면서 이런 접근으로는 한계가 있다고 판단했다.
그래서 이를 조금 더 개념적으로, 직관적으로 받아들일 필요가 있다고 생각했다. 이전까지 단순히 기술적, 코드적으로 프로그래밍을 진행하면서 협업시에 겪었던 몇가지 문제들은 다음과 같았다.
- 컨벤션에 있어서 각자의 편의가 모두 다르다.
- 어떤 문제를 마주했을 때 이를 해결하기 위한 중심 생각이 싱크가 되지 않는다.
- 따라서 어떤 문제에 대해서 논의 할 때 서로 다른 관점으로 문제를 접근하게 되어 기준이 흔들린다.
프로그래밍 시 객체 지향 프로그래밍적 사고를 통해서 문제를 해석하면 동료를 설득할 때에도 설득력이 생기고 어떠한 기준에 입각해서 코드를 작성할 수 있기 때문에 중간에 생각이 바뀌더라도 큰 틀에서 규칙을 지킬 수도 있다고 생각한다.
객체 지향적 사고를 설명하기 위해서는 간단하게 그 전까지의 흐름을 이해할 필요가 있다.
절차지향 프로그래밍의 문제점
- 초기 프로그래밍언어와 방식은 절차적 프로그래밍이었다. 입력을 받아 명시된 순서대로 처리한 다음 결과를 리턴하는 방식으로, 단순하고 ‘논리’와 ‘기능’자체에 집중했다. 즉, '어떤 데이터를 어떻게 취급할 것인가?' 에 대해서는 신경을 쓰지 않았고 프로그램을 명령어의 목록으로 보는 패러다임이었다.
- 간단한 알고리즘이나 간단한 프로그램이라면 괜찮지만 프로그램의 복잡도가 조금만 올라가도 코드를 순서대로 나타내는 것이 불가능할 정로도 복잡해지는 문제가 생겼다. 코드가 복잡하게 얽히고설켜서 이해하기 어렵고 유지보수가 힘든 스파게티코드가 생기는 것이다.
- 당연한 얘기지만 다른사람이 보고 이해하는 것 뿐 아니라 작성자 조차도 유지보수에 어려움을 겪게 될 수 밖에 없다.
명령어가 많아지고, 코드의 흐름을 파악하는 것이 힘들어지기 때문이었다.
구조적 프로그래밍 (하향식 프로그래밍)의 등장
- 이러한 문제를 해결하기 위해서 고안된 것이 하향식 (Top-down)프로그래밍 방식이다. 프로그램을 프로시저 단위로 나누고 프로시저끼리 호출을 하는 구조적 프로그래밍 방식이다. 간단하게 말해서 큰 문제를 정의하고 이것들을 작은 단위로 쪼개서 해결해나가는 방식이다.
- 이로써 함수(프로시저)를 사용한 방식은 어느정도 절차지향 프로그래밍의 문제를 해결했지만 여전히 문제가 남아있었다.
- 데이터 자체는 구조화하지 않았다.
- GUI의 등장으로 실행 콘텐츠의 상태와 내용을 저장할 방법이 필요해졌다.
- 전역 변수가 많아져 충돌 가능성이 커지는 문제가 생겼다.
객체 지향 프로그래밍의 등장
- 위와 같은 문제를 포함한 다양한 문제들을(다른문제들은 어떤 것들이 더 있을까?) 해결하기 위해서 등장한 것이 OOP 이다.
- 객체 지향프로그래밍은 절차지향 프로그래밍과 구조적 프로그래밍의 코드의 문제를 해결하면서 데이터의 구조화문제 또한 해결할 수 있는 돌파구를 제공했다.
- 객체 지향프로그래밍은 하향식 프로그래밍과 다르게 작은 문제들을 해결할 수 있는 객체를 만든 뒤, 이 객체들을 조합해서 큰 문제를 해결하는 상향식(Bottom-up) 방식을 도입했다.
- 독립성/ 신뢰성이 높은 객체를 만들어 놓으면 해당 객체를 매번 수정하지 않고 재사용할 수 있으므로 개발에 들어가는 리소스를 상당히 줄일 수 있다.
이러한 객체지향 프로그래밍을 통한 데이터의 구조화를 통해서 코드의 중복이나 절차지향프로그래밍의 문제를 어느정도 해결할 수 있었다.
그러나 이또한 개발언어 및 컴퓨터 성능의 발전에 따른 프로그램의 복잡도 증가로 인해서 더 간결하게 정리해야할 필요성이 대두될 수 밖에 없다.
이러한 이해관계에 따라 클린아케텍쳐와 디자인패턴에 대한 탄생과 고민은 필연적으로 이어진 것 같다.
이에 대해선 자세하게 포스팅 할 예정이다.
그래서 객체 지향적 프로그래밍사고가 뭘까?
한줄로 요약하자면 실제 세계를 코드로 모델링하여 문제를 해결하는 사고방식 이다.
실제 세계를 코드로 모델링한다라..🤔 조금 난해 한 것 같다.
피부로 와닿기 위해서 실제 세계의 예시를 통해서 이해해보자.
먼저 실제 세계를 모델링하기 전, 공통 속성과 범주에 대해서 간단하게 이야기를 하자면,
실제세계의 사물은 각각의 속성
을 가진다.
예를들면 자전거, 버스, 지하철은 ‘탈 것’, ‘이동수단’ 이라는 속성을 가지고 사과, 바나나, 사탕 은 ‘음식’, ‘단맛’이라는 속성을 가진다.
이제 범주 에 대해서 설명하자면
예를들어 팬더, 원숭이, 대나무, 바나나를 둘둘 씩 엮을 때
- [팬더, 대나무], [원숭이, 바나나] 와 같이
관계
에 중점을 두고 묶는 방법이 있는 반면 - [팬더, 원숭이], [대나무, 바나나] 와 같이
범주
로 묶는 방법 있다.
범주라는 것은 사물들이 공통적인 속성을 가진다는 뜻이다. 또 이러한 범주는 더 큰 공통점이나 더 적은 공통점을 엮어서 새로운 범주로 묶을 수 있다.
내가 생각하는 객체지향적 사고는 공통적인 것을 묶고 일반화하여, 즉 추상화하고 이들 간의 상호작용을 통해서 문제를 해결하는 방법론 중 한가지이다.
이를 이해하기 위해 현실세계의 사례(도메인)에 객체지향적 사고를 대입해서 생각해보자.
파스타 전문점에 간 데브리프터
배가고픈 데브리프터(
본인;
이후 손님)가 식당에 가서 음식을 시키는 상황을 가정해보자.
다시 말한다. “식당에 가서 손님이 음식을 주문하는 과정”을 상황이다. 객체지향적 사고의 포인트는 하기 위해서는 문제상황을 정의하고 이에 대한 해결을 일반화하는 것에 있다. 요리를 어떻게하고, 재료를 어떻게 손질하고와 같은 문제는 ‘주문’과는 또 다른 문제이기 때문에 이를 위해서는 새로운 모델이 필요한 것이다.
- 메뉴판에는 알리오올리오, 라구파스타, 까르보나라 세 가지 메뉴가 있다.
- 손님은 메뉴판을 보고 음식을 주문한다.
- 주문된 음식을 요리사가 제조한다.
- 파스타가 제조된다.
객체지향적 사고에서 가장 중요한 것은? 당연히 객체이다. 따라서 이 과정에서 무엇이 객체인지를 정의해보자.
손님
메뉴판
메뉴 항목 (3종)
요리사
파스타 (3종)
이렇게 5개의 객체가 정의 될 수 있다.
사실 메뉴3종도 객체로 보는것이 조금 괴리감이 들긴하지만 메뉴판과 메뉴항목을 하나의 객체로 생각한다면
손님은 메뉴판을 주문하게 되는 것이지 어떤 요리를 주문할 수가 없다. ( 코드적으로 생각하면 아래와 같다 )
메뉴 아이템 객체들은 메뉴판객체안에 존재하고 각각의 아이템은 이름과 가격을 가진다.
// 메뉴객체만 있을 때
struct Menu {
init(cost) {...}
}
// 메뉴 아이템 객체가 함께 있을 때
struct Menu {
var items<MenuItem>
}
struct MenuItem {
init(name: String, price: Int) {}
}
이제 문제상황을 조금 더 객체 지향적으로 통역해보자.
→ 손님객체는 메뉴판 객체안의 메뉴아이템 객체들 중 하나를 선택한다. 이를 요리사 객체에 전달하고, 요리사 객체는 주문을 받은 메뉴아이템 객체에 해당하는 파스타 객체를 제조한다.
이렇게 객체를 중심으로 표현할 수 있다.
결론
객체 지향 프로그래밍적 사고는
- 실제 세계의 문제상황을 정의하고
- 이를 해결하기 위한 사물이나 대상을 추상화하여
- 상호작용을 통해서 프로그래밍 하는 것이다.
공부한 내용에 대한 결론으로 개인적인 생각을 적자면, 객체 지향 프로그래밍적 사고가 필요한 이유는 프로그래밍을 통해 해결하고자 하는 문제를 더 직관적이고 실제 세상의 질서로 이해할 수 있게 된다. 이 과정에서 복잡한 데이터들을 더 간결하고 재사용성을 높게 사용할 수 있고, 실제 상황에 맞게 모델링 할 수 있게 되기 때문이다.
'iOS' 카테고리의 다른 글
동기(sync)/비동기(Async) & 블로킹(blocking)/논블로킹(Non-blocking) (0) | 2024.08.22 |
---|---|
객체지향 프로그래밍적 사고 - 2 (0) | 2024.08.16 |
.DS_Store 파일이란? (0) | 2024.04.16 |
[iOS] Font Size, Frame에 Text 맞추기, adjustsFontSizeToFitWidth, minimumScaleFactor, sizeToFit (0) | 2023.10.21 |
[iOS][Swift][UIKit] UIPickerView의 그라데이션넣기(gradient). (0) | 2023.09.04 |