객체 지향 프로그래밍이란 문제를 여러 개의 객체 단위로 나눠 작업하는 방식..
객체들이 서로 유기적으로 상호작용하는 프로그래밍 이론
프로그래밍에서의 객체는
데이터 분산을 막기 위해 데이터와 기능을 하나로 묶은 그룹.
즉 데이터와 기능들로 묶인 것들이 서로상호작용하게 만드는 것을 지향한다는 것이 OOP라고 한다.
EX) JAVA , C#, VISUAL BASIC, SWIFT, PYTHON등등
But
절차 지향 프로그래밍이란 것도 있는데 굳이 객체 지향 프로그래밍을
해야되는 이유는 뭘까?
- 코드를 적절히 잘 분류할 수 있어야한다. (분류)
- 경우에 따라 특정 모듈을 통째로 변경해야한다. (교체)
데이터에 대한 순서를 파악하고,
필요한 기능을 함수로 만들어 절차적으로 진행시키는 방법.
- 객체나 클래스를 만들 필요없이 바로 프로그램을 코딩할 수 있다.
- 필요한 기능을 함수로 만들어 두기 때문에 같은 코드를 복사하지 않고 호출하여 사용할 수 있다.
- 프로그램의 흐름을 쉽게 추적할 수 있다.!
- 각 코드가 매우 유기성이 높기 때문에 수정하기가 힘들다. (새로운 데이터나 기능을 추가하기가 어려움)
- 프로그램 전체에서 코드를 재사용 할 수가 없어 프로젝트 개발비용과 시간이 늘어날 수 있다.
- 디버그(오류 검사)가 어렵다.
- 모듈화, 캡슐화로 인해 유지보수에 용이하다.
- 객체지향적이기 때문에 현실 세계와 유사성에 의해 코드를 이해하기 쉽게 만든다. -> 가독성이 좋다.
- 객체는 그 자체가 하나의 프로그램이기 때문에 다른 프로그램에서 재사용이 가능하다. -> 큰 규모의 프로그래밍에 유리하다.
- 대부분의 객체 지향 프로그램은 속도가 상대적으로 느려지고 많은 양의 메모리를 사용하는 경향이 있다.
- 현실 세계와 유사성에 의해 코드를 이해하기 쉽게 만드는 만큰 설계 과정에 시간이 많이 투자된다.
그래서 객체지향 프로그래밍을 왜 써야 할까?
위의 장단점을 비교해보자면,
절차지향의 후발지향인 객체지향언어는
❗ 선발주자의 단점들, 니즈를 보완OR 개선하여 출시하므로, 기능 혹은 편의성에서 많은 이점을 가진다.
❗ 또한 대규모 프로젝트들이 많아진 현재 객체지향은 생산성과 유지보수 용이성을 높이는 개발방법론이다.
❗ 따라서 객체지향이 가지는 장점들 덕분에 개발자간의 코드 공유가 쉬워지고, 서비스의 규모가 증가함에 따라 더욱 더 단단한 프로그래밍을 가능하게했다.
OOP의 특성으로는 4가지가 있다.
- 데이터와 코드의 형태를 외부로부터 알수 없게 하고,
데이터의 구조와 역할, 기능을 하나의 캡슐형태로 만드는 방법.
- private를 통해 접근을 제어하고
Getter, setter등의 메서드를 통해 간접적으로 접근을 허용
- 불필요한 정보를 감출수 있다.
- 객체의 공통적인 속성과 기능을 추출 하여 정의
- 공통적인 특징들을 묶어서 만들어 놓은 설계기법
- 목적과 관련이 없는 부분을 제거하여 필요한 부분만을 표현하기위한 개념
- 기존 상위클래스에 기능을 가져와 재사용할 수 있으면서도 동시에
새로운 하위클래스에 새로운 기능도 추가
- OOP에서 이를 부모 클래스, 자식클래스라 표현,
상속이 필요한 이유는 코드의 중복을 없애기 위해서다.
- 자식 객체는 상속된 부모 객체의 구성에 따라 변수,메소드에 접근이 가능하며,
부모가 추상 객체일 경우 추상 메서드와 오버라이딩을 통해 부모객체
메서드를 구현하거나 다룰 수 있다.
또한 추상 메서드의 구현은 상속받은 자식 객체에서 이루어야함.
한 객체가 상속받은 기능을 확장하거나 수정하여 재정의 하는것.
오버로딩, 오버라이딩 등으로 구현.
오버라이딩은 상속받은 메서드를 재정의하여 내가 필요한 기능으로 사용하는 것,
오버로딩은 하나의 클래스에서 메서드끼리 같은 이름을 사용하지만,
매개변수나 데이터타입을 달리 만들어서 각기 다른 메서드로 사용이 가능하다.
코드의 재사용성을 늘려주어 유지보수가 용이하도록 도와줌.
객체 지향에도 지켜줘야 할 5가지 원칙이 있었다.
SRP 단일 책임 원칙
OCP 개방 폐쇄 원칙
LSP 리스코프 치환 원칙
ISP 인터페이스 분리원칙
DIP 의존 역전 원칙
SRP (Single Responsibility principle)
THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.
⭕ 모든 클래스는 각각 하나의 기능만 가진다는 의미
해당클래스가 제공하는 서비스는 단 하나의 모듈을 수행하는데 집중해야함.
가독성 향상, 유지보수 용이라는 이점이 있다.
💨한 줄 요약
CLASS 하나당 하나의 기능을 가지게 해라
OCP (Open Close Principle)
YOU SHOULD BE ABLE TO EXTEND A CLASSES BEHAVIOR, WITHOUT MODIFYING IT.
⭕ 모든 구성요소는 확장에는 열려있고,변경에는 닫혀 있어야한다.
💨한 줄 요약
기존 구성요소를 건들지 않고 쉽게 확장이 가능하게 만들어야 한다.
수정하지 말고 기능을 추가하자.
인터페이스로 추상메소드를 묶고 개별 구현 클래스를 만든다
LSP (The Liskov Substitution Principle)
FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT.
⭕ 부모 클래스를 상속한 자식 클래스는 부모 클래스의 역할을 정확히 해내야한다.
서브타입은 언제나 기반타입으로 교체할 수 있어야한다.
상속받은 클래스는 부모 클래스와 동일한 동작을 해야
재활용 가능성이 높아진다.
💨한 줄 요약
올바르게 인터페이스를 상속해서 기능추가를 해야한다.
ISP (Interface Segragation Principle)
인터페이스를 더 잘게 사용하자.
CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.
⭕ 자신이 사용하지 않는 인터페이스는 구현하지 말아야한다는 원칙,
하나의 큰 인터페이스를 상속받기보다 구체적이고, 작은 단위들로 분리해야한다.
✔ ISP ▶ 인터페이스의 단일 책임.
✔ SRP ▶ 클래스의 단일 책임.
💨한 줄 요약
꼭 필요한 인터페이스만 상속받자.
자바에서는 Upcasting과 Downcasting이라는 개념이 존재한다.
Upcasting: 자식객체를 부모타입의 객체로 치환하는 것
Downcasting: 부모객체를 자식타입의 객체로 치환하는 것
해당하는 자원을 사용하기위해 부모나 자식객체의 타입으로 치환해서 호환성을 맞춘다.
DIP (Dependent Inversion Principle)
언제든지 역전 될만한 상황이 나올수 있음.
LIBARARY 예제
A. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
B. ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS
‘상위 모듈은 하위 모듈에 의존해서는 안된다. 둘 다 추상화에 의존해야한다.’,
‘추상화는 구체적인 것에 의존해서는 안된다. 구체적인 것은 추상화에 의존해야한다.’
Why ?
EX) 나는 갤럭시 폰을 사용하는 USER이다.
갤럭시는 시즌별로 지속적으로 버전이 업그레이드 되며, 가변적이다.
내가 갤럭시폰으로 아이폰의 기본사진만큼의 고화질영상을 얻고 싶을때
=> 나는 갤럭시 폰을 의존하는 유저이므로, 갤럭시 핸드폰에 기능을 수정해야한다.
But
내가 스마트폰을 의존하게 된다면, 핸드폰에대한 선택지가 넓어진다.
따라서 기능을 가지고 있는 아이폰을 선택(구현)하면 된다.
즉 유저는 자신보다 변화하기 쉬운 갤럭시에 의존하던 관계에서
중간에 추상화된 스마트폰을 추가해서 의존관계를 역전시킨다.
"유저는 갤럭시의 새로운 출시에도 영향을 받지 않고 아이폰을 사용한다."
💨한 줄 요약
의존이 역전되어 구체적인 클래스의 변화에 영향을 받지 않게 한다.