본문 바로가기

Programinng/Java

자바(Java) - 객체지향이란?

객체 지향 프로그래밍(Object Orented Programing)이란 무엇일까?


처음 객체지향을 접하는 개발자들이 가장 혼란스러워 하는 부분이다.

나도 처음에 객체지향 개념을 익히는데 많은 어려움이 있었다. (물론 지금도 잘 안다고 할 순없지만..)


여러 Fundamental책에서 흔히 말하길 객체(Object)란,  '일상 생활에서 표현 할 수 있는 모든 것'이라 말한다. 이말에 몇 가지 추가하겠다. 일상 생활에 표현 가능한 모든것 + 처리과정, 정보, 오류등 눈에 보이지 않은 것들도 모두 Object로 표현한다. 



객체지향 프로그래밍에서는 몇가지 원리 · 원칙(Principle)이 존재한다.

'변하는것을 캡슐화하라.'

'구현에 의존하기 보다는 인터페이스에 의존 하도록 코딩하라.'

'각 클래스는 변경 요인이 오직 하나이어야 한다.'

'클래스는 행동과 기능에 관한 것이다.'


객체지향의 가장 큰 특징은 '유지보수성', '재사용성', '가독성'이며, 객체지향 원칙들의 대부분은 바로 이 세 가지를 지킬 수 있는 원칙들 말한다.


흔히 SOLID라 부르는 객체 지향 원칙이 있다.


SRP(Single Reponsibility Principle) 단일 책임의 원칙

클래스는 오직 책임이 하나이어야만 한다. 즉 변경 요인이 하나이어야 한다는것이다. 요구사항이 변경 되었을때, 하나의 클래스가 너무 많은 일을 하고 있다면 수정도, 가독성도 어렵다. 또 너무 거대한 클래스는 재사용하기도 힘들다. (자동차 와이퍼는 창문앞에서 좌우로 움직이기만 하면 되지, 워셔액까지 관리할 필요는 없지 않은가?)


OCP(Open-Closed Principle) 개방 폐쇄의 원칙

클래스는 확장에는 열려 있지만, 수정에는 닫혀 있어야 한다. 객체지향에서는 공통적인 부분을 추상하여 SubClassing하여 사용한다. 이것은 클래스 확장에 열려있다는 것이다. 하지만, 서브클래싱을 하고 Override 많이 사용한다면 이것은 처음 설계된 슈퍼클래스를 수정한다는 것이고, 처음부터 설계가 잘못 됐다는 것을 의미한다. 당신이 설계한 클래스가 상속이 된 후, 너무 많은 수정을 하고 있다면 설계를 다시 한번 생각해 봐야 할때가 됐다.


LSP(Liskov Substitution Principle) 리스코프 치환 원칙

SubClass는 SuperClass가 사용되는 곳에 대체 될 수 있어야 한다. 이는 OCP와 비슷한 맥락인데, SubClassing한 후, 서브클래스에서 Override를 사용하여 코드를 많이 수정하였다면 슈퍼클래스를 대체할 수 없다는 뜻이다. 


ISP(Interface Segregation  Principle) 인터페이스 분리의 원칙

Interface는 구현 스펙을 정의한다. 이를 분리하라는 것은 거대한 클래스(Large Class)가 있다면, 그것을 쪼개라는 뜻이다. 


DIP(Dependency Inversion   Principle) 의존관계 역전의 원칙

구현에 의존하기 보다는 인터페이스에 의존 하도록 코딩한다.


이외에도 몇 가지 존재한다.


DRY(Don't Repeat Yourself) 반복 금지의 원리

중복 되는 코드를 추출하여 한곳에 두어 사용한다.


Hollywood  Principle 헐리우드 원칙

의존성 부패를 방지한다. 고수준 구성요소가 저수준 구성요소에 의존하고, 그 저수준 구성요소는 다시 고수준 구성요소에 의존하고.. 이렇게 꼬이는 것을 의존성 부패라 한다.

  이는 저 수준 구성요소를 호출할때, 어떻게 그 구성요소들을 사용할지는 고수준 구성요소에서 결정하게 된다. 


Law of demeter 최소 지식의 원칙

디미터 법칙은 상호 작용하는 Object가 어떤식으로 작용하는지 몰라도 된다. 사용하는 객체는 그 객체의 초소한의 지식만 가지고 있으면 된다. 

 흔히 디미터 법칙은 "클래스 C의 메소드 f는 다음 객체의 메소드만 호출해야 한다"고 주장한다.

- 클래스 C

- f가 생성한 객체

- f인수로 넘오온 객체

- C인스턴스 변수에 저장된 객체

아래와 같은 코드가 그 원칙을 여긴 경우다. 이것을 흔히 기차 충돌이라 말한다.

doc.getFly().flying();

doc객체가 flying에 대해 너무 많은걸 알고 있기 때문에 커플링 관계가 높다고 할 수 있다. 이는 날으는 행동에 변경이 있을 경우 사용하는 모든 객체에 변화를 준다(Shotgun Surgery - 변경할때 마다 코드드를 수정해야 된다). 이럴 경우 다음과 같이 위임(Delegation)을 사용한다.

doc.flying();




자바 랭기지가 처음이라면 Head First Java,

객체지향을 좀 더 알고 싶다면 Head First Object Oriented Analysis Design을 추천한다.