https://st-lab.tistory.com/151
https://www.youtube.com/watch?v=3etKkkna-f0
절차지향 언어 : C언어
객체지향 언어 : Java, Python, JS ...
위와 같은 분류는 우리에게 오해를 불러 일으킬 수 있다.
"C 언어는 절차지향 언어이기 때문에 절차적으로 설계(구현)를 할 수 밖에 없고 , 자바나 파이썬 같은 객체지향 언어들은 절차적으로 설계(구현)가 불가능 하고 , 객체지향적으로 설계(구현) 할 수 밖에 없나보다."
하지만 우리는 자바로도 절차적인 코드를 구현 할 수 있고 , C언어로도 유사 객체지향 으로 구현 할수도 있다. 더군다나 모든 코드는 "기본적인 절차" 즉 틀이 있기 때문에 위와 같은 말은 "지향" 이라는 단어를 정확히 이해하지 못했을 때 나오게 된다.
결과적으로 "지향" 이라는 말은 코딩하는 방식 또는 방법론의 차이이다. 즉, 특정 언어가 특정 지향만 지원한다 가능하다 라는 뜻이 아니라는 것이다.
우리는 이러한 사실을 통해 , 객체지향 반대가 절차지향이다. 라는 오해도 해결 할 수 있다.
절차지향, 객체지향은 코딩하는 방식과 방법론의 차이이며 대개 절차적 프로그래밍은 데이터를 중심으로 함수를 만들어 구현 하고 객체지향은 데이터와 기능(메서드)들을 묶어 하나의 객체로 생성하여 객체간의 상호작용을 이용하여 구현 한다.
이러한 접근방법의 차이점이 있을 뿐이지 반대되는 개념이 아니라는 사실을 인지하자.
바로 언어를 지원하는 기능과 그언어의 특성에 있다. 지원하는 기능과 특성이 절차적 프로그래밍 접근을 하기가 더 유리한지 혹은 그 반대인지 에 따라서 분류를 한다.
대개 절차적 언어와 객체지향 언어가 나뉘는 기준은
요즘 대부분의 상용언어들은 객제지향 언어들이 많은데 이러한 이유는 객체지향의 등장 배경을 알면 이해할 수 있다.
절차적 언어의 단점은 데이터를 중심으로 함수를 만들어 함수들이 특정 순서대로 실행되기 때문에 , 복잡한 알고리즘 또는 복잡한 로직을 구현하는 서비스를 구현하다 보면 코드를 볼때 사람이 읽으면서 동작을 이해할 수 없게 되는 스파게티 코드가 되어버리는 단점이 있다.
이는 뒤에서 예시를 통해 구체적으로 보겠다.
소프트웨어가 발전하면서, 요구사항도 복잡해지게 되었고 그러한 요구사항을 구현하기 위해서 우리는 복잡한 알고리즘 또는 복잡한 로직을 구현 해야하는데 이러한 부분에서 절차적언어의 단점이 부각되고 이러한 해결책으로 나온것이 객체지향적 프로그래밍이다.
객체는 현실의 무언가에 대응하는 개념이다. 자바에서는 Class 라는 개념을 이용하여 객체를 정의할 수 있다. Class 는 객체를 표현하는 하나의 수단이기때문에 Class = 객체 가 아니라는 점을 생각하자.
각 객체들은 "역할"과 "책임"이 존재한다. 또한 각 객체들은 서로 다른 객체들과 "협력" 하며 상호작용 한다.
ex) 커피숍 : 주문을 받아 주문받은 음료를 만들고, 음료가 준비되면 주문벨을 울린다.
주문을 받는 객체와 음료를 만드는 객체 , 주문벨을 울리는 객체 들이 서로 협력하여 커피숍을 운영한다.
위의 예시에서 음료를 만드는 객체는 고객이 주문한 음료를 정확하게 알고 만들어야할 책임을 갖는다.
위의 예시에서 주문을 받는객체와 주문벨을 울리는 객체가 A라는 객체일때 , A는 주문을 받는 책임과 주문벨을 울리는 책임을 가진 역할을 하는 객체는 A이다.
객체는 메시지를 통해 다른 객체에 책임을 다하라고 요구한다.
무엇을 해야할지 요구하고 , 요구사항을 어떻게 할지는 요청받은 객체의 자율에 맡긴다.
객체의 자율에 맡기면서 우리가 가지는 이점은 , 메시지를 보내는 객체가 무엇을 해야할지만 알려주고 어떻게 하는지 신경 쓰지 않아도 된다.
즉 각 객체들은 역할 과 책임이 명확하게 분리되어있기 때문에 각 상황에 필요한 역할을 가진 객체에게 우리는 넘겨주기만 하면된다. 복잡한 로직 또는 알고리즘이더라도 스파게티 코드가 되는 가능성을 줄 일 수 있다.
또한 확장성 면에서도 이점을 가진다.
주문을 받는 객체가 음료를 만드는 객체의 만드는 방법등을 알고 있어야 한다면, 또는 반대로 음료를 만드는 객체가 주문을 받는객체가 알고 있는 레시피대로 음료를 만들어야한다면 만약 음료를 만드는 객체가 다른 객체로 바뀌었을 때 추가적인 일이 생긴다.
하지만 어떻게 할지에 대해 객체 자율에 맡긴다면 어떤 객체가 오든 해당 책임을 다할 수 있다면 전체 목표 또는 다른 객체에 영향을 미치지 않기 때문에 확장성 면에서 강점을 가진다.
접근제어 지시자를 통해 정보은닉의 기능을 제공하고 , 여러가지 형태의 객체를 디자인 할 수 있는 특성
ex) 싱클톤 패턴
캡슐화는 정보은닉이라는 특징을 가지고 있다.
접근제어 지시자를 통해 객체에 직접적인 접근을 필요에 따라 막을 수 있다 즉, 외부에서 내부의 정보에 직접 접근하거나 변경 하는것을 제어 할 수 있다.
이를 통해 유지보수나 확장시에 오류의 범위를 최소화 할 수 있다. 더하여 객체 내 정보 손상, 오용을 방지할 수 있고 클래스 내부의 로직 (조작법) 이 바뀌어도 호출하는 클래스의 로직(사용법) 자체는 바뀌지 않는다.
이러한 독립성을 가질 수 있기때문에 확장성,이식성 면에서 이점을 가진다. (모듈성)
상위 클래스의 특징을 하위클래스에서 상속받아 코드의 중복 제거, 코드 재사용성 증대 할 수 있다.
객체 모델링을 할 때 , 공통적인 속성들을 묶는다.
클래스를 정의 할때 불필요한 부분을 생략하고 중요한 속성들로 개략화 하거나 , 공통적인 속성들을 가지는 객체들을 추상클래스나 인터페이스를 통해 추상화를 할 수 있다.
이로인해 중복코드를 줄일 수 있다는 장점이 있다.
코드가 간결해지기 때문에 생산성이 증가하고 , 공통적인 속성들 , 중요한 속성들로 묶여있기때문에 가독성도 증가 하고 모든 클래스를 일일이 유지보수 할때 보다 , 공통적인 속성들로 묶여있다면 슈퍼클래스만 수정을 하면 되기 때문에 코드의 재사용성 , 유지보수시 시간단축등의 효과가 있다.
프로그램 언어의 다형성은 그 프로그래밍 언어의 자료형 체계의 성질을 나타내는 것으로, 프로그램 언어의 각 요소들(상수, 변수, 식, 오브젝트, 함수, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다. 반댓말은 단형성으로, 프로그램 언어의 각 요소가 한가지 형태만 가지는 성질을 가리킨다.
By 위키피디아
즉 다형성이란 하나의 객체에 여러가지 타입을 대입할 수있다 를 의미한다.
다형성을 구현하는 방법으로는 대표적으로 오버로딩, 오버라이딩, 인터페이스, 추상클래스 등이 있다.
다형성을 통해 역할과 구현을 분리해서 서비스의 구현기능을 유연하게 변경 할 수 있고 확장성에서도 큰 이점을 가진다.
ex) 역할(자동차) - 구현(아반떼 , benz E 아방가르드, 테슬라 모델Y)
--> 구현체가 바뀌어도 구현체 내부 구조를 알 필요가 없기 때문에 확장성 면에서 Good!
다형성의 본질은 클라이언트를 변경하지 않고 서버의 구현기능을 유연하게 변경 가능 하는것에 있다.
Spring을 예로 들자면
클라이언트에게 우리가 ViewExamService 라는 서비스를 제공한다고 가정했을 때 , 현재는 JpaViewExamRepository 라는 클래스를 이용하고 있지만 유지보수를 통해 새로운 클래스 MybatisViewExamRepository 라는 클래스를 이용해야한다면 (같은 interface를 구현하는 클래스라고 가정하였을 때) 서비스 측의 로직을 바꾸지 않아도 된다. Bean 등록은 최신화 해야겠지만 .
https://github.com/JIWEON-JEONG/Study/tree/master/src/com/company/oop
OOP 의 개념을 생각하면서 만든 CoffeeShop 코드이다.
위의 개념들을 생각하며 , 코드를 보면 개념을 적립하는데 도움이 될 것이다.