객체 지향 프로그래밍에 대하여
객체 지향 프로그래밍은 무엇인가
Object-Oriented Programming (OOP)
객체지향 프로그래밍은 설계 방법론이자 개념의 일종입니다.
컴퓨터 프로그램을 객체들의 모임으로 생각해 프로그래밍을 좀 더 유연하고 변경하기 쉽게, 즉 유지보수가 원할하게 하기위해 생겨난 패러다임입니다.
객체지향 전에는 주로 절차지향으로 프로그래밍을 하였습니다.
컴퓨터는 입력을 받아 명시된 순서대로 처리한후, 그것을 결과로 나타내는것인 컴퓨터 친화적인 방식이였습니다.
이때문에 프로그래밍은 어떤 논리를 어떤 순서대로 써내려 가는것인가로 간주되었습니다.
절차지향적인 방식때문에 우리는 프로그램 자체가 가지게 되는 기능에만 관심을 가졌지 정작 이 프로그램들이 어떤 데이터를 취급하는가에 대해 관심이 없게 되었습니다.
이러한 과거의 절차지향적인 방식은 조금만 프로그램 코드들이 복잡해지면 유기적으로 연결이 불가능적으로 꼬인 “스파게티코드” 를 만들게 되었습니다.
이런 절차지향적인 프로그래밍 방식은 성능자체는 우수하였지만 다른 사람과 협업을 하고자할때, 다른사람이 코드를 보고 이해하는것이 불가능할정도였습니다.
절차지향 프로그래밍의 고질적인 문제를 해결하기위해 에츠허르 다익스트라 가 함수형 프로그래밍 을 제시하면서 이런 위기를 벗어나게 되었습니다.
함수형 프로그래밍의 등장
절차지향적인 한계를 극복하기위해 함수형 프로그래밍 패러다임이 등장하였지만 이 역시 문제에 당면하였습니다.
데이터를 처리하는 방법만을 구조화했을뿐 그 데이터 자체를 구조화 하지못하였습니다.
이는 전역 네임스페이스 포화 문제를 낳았고, Execution Context 를 저장할 방법이 딱히 없어지는것이 문제였습니다.
또한 함수형 프로그래밍은 객체가 상태를 갖게 된다는것이 문제였습니다
다른 데이터가 전혀 다른 함수에 전달되서 다른 결과를 return 하는 문제가 발생 하고 그런 가능성을 대비하고자
개발자는 함수의 실행에 영향을 받는 모든 변수를 조사해야했습니다. 하지만 이것은 코드의 수가 점점 많아지는 대형 프로젝트에서는
모든 코드의 조사가 어려웠고, 때문에 함수가 접근 할 수있는 데이터의 범위에 별 다른 제한을 걸어두어야만 했습니다.
객체지향 프로그래밍의 특징
1. 캡슐화(Encapsulation)
연관 있는 변수와 함수를 하나의 단위로 묶는것을 말합니다.
캡슐화를 통해 객체의 데이터는 외부에서 직접 접근하지 못하게 제한하고 함수를 통해서만 조작이 가능하게 하는 작업입니다.
프로그램 내부의 구현을 외부로 들어나게 하지않아 모듈내의 응집도는 높이며, 모듈간의 결합도는 떨어트려 유연함과 유지보수성은 높혔습니다.
때문에 클래스의 외부에선 특성 메소드로 통해 접근이 가능하며 클래스 내부에서 어떤 방식으로 처리가 이루어지는지는 알 수가 없습니다.
2. 상속(Inheritance)
우리 개발자들은 중복적인 작업을 하는것을 싫어하는데 이를 해결 할수있는것이 상속입니다.
상속은 자식 클래스가 부모의 특성과 기능을 그대로 물려받는것을 말합니다.
상속을 통해 중복적인 작업을 해결할수있게 되었지만
하지만 이렇게 상속을 그대로 물려받는것만 할 수있다면 객체지향의 유연함이 훼손됩니다.
만약 기능의 일부분만을 변경해 사용하고 싶다면 상속받은 그 기능만을 수정해 다시 정의하게 되는데
이것을 오버라이딩(Overring) 이라고 합니다.
상속은 캡슐화를 유지하면서도 클래스의 재사용성이 용이하게 해줍니다.
3. 다형성(Polymorphism)
다형성은 하나의 변수 또는 함수가 상황에 따라 다른 의미로 해석될 수 있는 것을 말합니다.
같은 타입이지만 실행결과가 각각 다른 객체를 이용할수있습니다.
일반적으로 서브타입 다형성(Subtype Polymorphism / Inclusion Polymorphism / Subtyping), 매개변수 다형성(Parametric Polymorphism), 임시 다형성(Ad hoc Polymorphism), 강제 다형성(Coercion Polymorphism) 등이 있지만 추후에 자세히 다루도록 하겠습니다.
객체지향의 장단점
- 객체지향에서 데이터 클래스의 상속이라는 개념은 뛰어나고 편리하지만 굉장히 복잡한 특성을 갖게 합니다.
이 특성 덕분에 우리는 자료분석, 개발시간 단축, 원활한 유지보수등을 꾀할수있지만 코드를 만드는데 난이도가 상승합니다.
- 캡슐화와 격리 구조 설계로 인해 성능이 하락됩니다.
또한 객체간의 정보교환이 모두 메세지교환들로 일어나므로 시스템에 많은 overhead 를 발생시킵니다.
- 객체 각각 따로 나눠서 사용하는데 주력하다보니 서로 비슷한 처리를 하는 코드가 서로 건드릴수없게 되었고 이를 해결하기위해
getter, setter 의 사용이 빈번해졌습니다.
이때문에 객체지향에서 캡슐화가 깨지게 되고 public 으로 공개한경우나 다름없는 상황이 되어버려 객체지향의 특성이 훼손되었습니다.
이러한 단점때문에 또다른 프로그래밍 패러다임이 필요했습니다. (AOP)