객체지향이란?
객체지향이란?
프로그래밍의 패러다임 중 하나로, 프로그램(코드) 를 컴퓨터 명령어의 목록으로 보는것이 아닌, 객체의 단위로 묶어서 문제 해결을 하는 방식을 말한다.
그러니까, 단순히 기능만 구현해내는것이 아니라, 특정 작업을 하는 코드의 모음을 묶어서 문제를 해결하는 방식이다.
객체지향의 4요소
각각의 4 요소는 언어차원에서 지원하는 경우도 있고, 아닌 경우도 있다.
객체지향은 프로그래밍 패러다임 중 하나이기때문에 꼭 언어차원에서 지원되지 않더라도 사용 할 수 있고, 맨 밑에서는 지원하는 언어의 경우 어떤 방식과 키워드를 통해 지원하는지 밑에서 언급하고자 한다.
- 캡슐화
데이터를 묶는것을 말한다. 변수나 함수를 하나의 단위로 묶곤 한다. - 정보 은닉
객체 내부와 외부에서 접근 가능한 정보를 숨기는 것을 말한다. 밖에서 접근 가능한 내용과 안에서 접근 가능한 내용을 분리하여 유지보수를 편하게 할 수 있다. - 상속
자식을 만들어서 부모의 기능을 그대로 물려 받을 수 있게 하는 내용이다. 부모의 특정 기능을 받아와서 기능의 일부분만을 바꾸거나(overriding), 새로이 기능을 추가 할 수 있다. - 다형성
자식이 부모의 함수를 덮어쓰는 경우(overloading)가 대표적인 예시가 될 수 있다.
객체지향의 5원칙
객체지향이라는 프로그래밍 패러다임: 방법론을 제시한 초기 프로그래머들은 '이런 요소들이 있어야 올바른 방식으로 객체지향 코드를 작성한것이다' 라고 주장하며 다음과 같은 규칙을 만들었다.
- Single Responsibility Principle (SRP)
: 객체는 오직 하나의 책임만을 가져야 한다.
나무위키에서는 이에 관한 좋은 예시를 찾아 볼 수 있다.사칙연산 함수를 가지고 있는 계산 클래스가 있다고 치자. 이 상태의 계산 클래스는 오직 사칙연산 기능만을 책임진다. 만일 프로그램이 대대적으로 공사를 들어가게 되더라도 계산 클래스가 수정될만한 사유는 누가 봐도 사칙연산 함수와 관련 된 문제 뿐이다. 이처럼 단일 책임 원칙은 클래스의 목적을 명확히 함으로써 구조가 난잡해지거나 수정 사항이 불필요하게 넓게 퍼지는 것을 예방하고 기능을 명확히 분리할 수 있게 한다.
쉽게 말해서, 객체지향적으로 코드를 작성하며 특정 기능과 값들을 묶을때 '명확히' 묶어야 한다는것이다.
GUI면 GUI코드만, 연산 코드면 코드만.
Open-Closed Principle (OCP)
: 객체의 경우 확장에 대해서는 개방(open)적이여야 하고, 수정에 대해서는 폐쇄(Closed)적이어야 한다. 말이 좀 어렵다. 객체의 확장과 수정이라니, 대체 뭘까? 선풍기라는 객체를 생각해보자. 이 객체는 '바람세기', '회전 유무', '회전 각도' 라는 속성을 갖고있다.
그리고 '바람 세기 높이기', '바람 세기 낮추기' 라는 기능을 갖고있다고 생각해보자. 여러사람이서 선풍기를 공유해서 쓰고 있다고 가정하겠다.그런데 이 선풍기를 분해해서 '바람 세기 높이기' 의 기능을 직접 수정하는 일은 있어서는 안될것이다. 만약 누군가가 "아!! 이거 바람 세기좀 한번에 많이 높이면 안되나!!" 라고 말하면서 해당 버튼의 기능을 수정하면, 해당 선풍기를 사용하는 다른 사용자들은 혼란을 겪을것이다. 다만, 선풍기 위에다가 "바람세기를 2씩 늘려주는 기구" 를 설치하는것은 괜찮다는것이다. 왜냐하면 기존 선풍기 사용법을 알던 사람들도 무리 없이 사용 가능하고, 해당 객체를 누군가 가져다 쓴다고 해도 생각한것과 다르게 기능이 작동할 일 이 없기 때문이다.
Liskov Substituition Principle (LSP)
: 자식은 언제나 부모를 대체 할 수 있어야 한다.
상속을 통해서 이 문제는 해결이 된다.Interface Segregation Principle (ISP)
: "클라이언트의 경우, 사용하지 않는 메소드에 의존 관계를 맺으면 안된다." - 로버트 C 마틴
SRP에서는 명확히 묶어서 유지보수의 편의성을 지키도록 하였다. ISP는 인터페이스를 통한 다른 해결방법을 말한다.
사람이라는 요소에 성별, 직장, 종교와 같은 요소들을 덧붙이고 싶을 때, SRP였다면 클래스를 여러가지를 만들었을것이다.
ISP는 이것을 여러가지 인터페이스로 잘게 쪼개어 해당하는 클래스에 붙여 쓰는것을 말한다.Dependency Inversion Principle (DIP) :
: "자신보다 변하기 쉬운 것에는 의존하지 말 것"
만약 케이스라는 인터페이스 밑에 가죽 케이스와 실리콘 케이스가 있고, 휴대폰과 실리콘 케이스 사이에 의존관계가 있다고 치자.
만약 케이스를 변경하고 싶다면 어떻게 해야 할까?
실리콘 케이스 인터페이스를 기준으로 휴대폰의 클래스를 설계해두었다면, 휴대폰 케이스를 변경할 때 휴대폰 클래스에 영향을 주게 될 것이다.
이는 결과적으로 불안정한 구조라는 결과를 초래하게 된다.
DIP를 고려한 설계라면 이러한 경우 휴대폰에서 실리콘케이스 인터페이스를 사용하는것이 아닌 케이스 인터페이스를 사용해야한다고 말한다.
언어차원에서 제공하는 객체지향
대부분의 현대 언어에서는 객체지향을 제공한다. 아까 말한 객체지향의 4요소는 다음과 같은 방식으로 구현이 되는데..
- 캡슐화: class
- 정보 은닉: public, protected, private 같은 키워드를 사용. 그러나 파이썬의 경우 언어차원에서 구현되어 있지 않아 이름 앞에 _를 붙여 public / private을 구분
- 상속: extends
- 다형성: overloading 같은 기능
그런데 사실, 객체지향은 프로그래밍 패러다임 중 하나이기때문에 꼭 언어차원에서 지원되지 않더라도 사용 할 수 있다.
그러니 'C언어는 객체지향 프로그래밍이 불가능한가요?' 라는 질문을 받으면 이렇게 답해주자. '객체지향은 프로그래밍 패러다임이에요!'
대표적인 예시로는 Linux 커널이 있겠다. 즐거운 공부되었길.
Comments
Post a Comment