객체 지향의 특성인 추상화,상속,은닉,재사용,인터페이스
등 여러 곳에서 객체 지향으로 개발 시작
객체 지향이란 현실에 존재하는 사물을 있는 그대로 모델링 하고, 이들의 행위
와 속성
을 정의하고, 절차지향적 개발이 아닌 객체가 중심이 되어 실제 사물이 동작하는 방식으로 설계
하기 시작
사물 -> 객체
, 사물이 하는 행위 -> 메서드
, 사물의 속성 -> 변수
객체 == 사물 == Object
이것이 완전하지 않을 시엔 불완전 객체
상태유지(객체의 상태)
객체는 상태 정보를 저장하고, 유지되어야 하며 이러한 속성은 변수로 정의되어야함 -> 이러한 속성 값이 바뀜으로 인하여, 객체의 상태가 변경 될 수 있어야 한다
기능제공(객체의 책임)
객체는 Method를 통해서 기능을 제공해야 한다 -> 이 부분은 캡슐화와 연관이 있으며, 외부로 부터 직접 속성에 접근하여 변경하는 것이 아닌 제공하는 Method로 기능이 제공 되어져야 한다
고유 식별자 제공(객체의 유일성)
각각의 객체는 고유한 식별자를 가져야 한다 -> ex) 카드번호, 계좌번호, 자동차 번호와 같은 속성을 통해서 각각 고유한 값을 줄 수 있으며, 이는 이후 Db에서 Unique Key 또는 Primary Key로 작성 가능하다
실제로 사물이 존재
하며, 이를 클래스로 정의한 객체 의미
ex)
자동차 렌탈 시스템 : 자동차, 고객, 직원
피시방 관리 시스템 : Pc, 직원, 공간, 책상 ...
웹 시스템에서 Service
에 해당, 이는 business logic
을 처리하는 부분
Business logic에서는 여러 객체를 서로 상호작용 하도록 함, 객체가 제공하는 오퍼레이션 method를 통하여 객체의 속성을 변경 시킴
ex)
사용자 관리 시스템 - 사용자 객체의 마지막 접속일자를 이용하여, 계정 만료, 비밀번호 초기화, 재등록 처리 등등
ATM 시스템 - 사용자(Object)의 Action에 따라, 계좌(Object)의 잔고 속성을 변경하는, 입금/출금 Logic 처리
객체 지향에서의 대부분 코딩은 각 객체의 기능을 정의하고 Business logic
을 처리하는 Service
에서 객체의 Method를 활용
하여, 여러 가지 조건을 확인한 후, 객체의 속성을 변경하는 작업이 주된 코딩
-> 각 객체의 속성
과 , 이러한 속성을 변경하거나 상태를 변경할 수 있는 오퍼레이션을 잘 정의
해야 함
캡슐화는 객체의 속성을 보호하기 위해서 사용
속성이 선언되었으나, 이의 상태를 변경하는 Method가 없다면, 잘못 선언된 속성
실물 객체가 가진 기능을 모두 제공해야 함
객체 안의 Method는 객체 안의 속성을 처리해야 하며, 다른 객체를 전달받아 해당 다른객체의 속성을 직접 처리하면 안된다
Getter/Setter Method
외부에서 내부 속성에 직접 접근하는 것이 아닌 Getter, Setter를 통해서 접근
CRUD Method : 데이터 처리를 위해 기본적인 CRUD METHOD 제공
Business Logic Method
생명 주기 처리 Method -> destory(), disconnect() ...
객체 지향 패러다임 중 하나인 추상화를 제공
-> 실제 Method가 어떻게 동작하는 지 외부에서 이해할 필요 X
재사용성 향상
무결성 보장
-> 캡슐화 코딩 시 변수는 private 메서드는 public, 메서드는 입력된 매개변수를 Validation 한 후에 실행하는 것이 기본
객체 지향에서 상속은 속성의 상속이 아닌, 하위로 내려갈수록 구체화 되는 것
프로그램 구조에 대한 이해도 향상
재사용성, 확장성, 유지보수성 향상
하나의 개체가 여러가지 형태로 변화하는 것 -> 오버라이딩 통해 가능
if 저글링일때 -> 무브, 레이스 -> 무브 이런식으로 코딩할 필요 X
객체지향에서 추상화 -> 모델링
구체적으로 공통적인 부분
, 또는 특정 특성
을 분리해서 재조합
하는 부분이 추상화
앞서 설명한 다형상 및 상속
은 모두 추상화에 속한다
좋은 소프트웨어 설계를 위해서는 결합도
는 낮추고 응집도
는 높여야함
결합도 : 모듈(클래스)간의 상호 의존 정도를 나타내는 지표
로 결합도가 낮으면 모듈간의 상호 의존성을 줄어들어서 객체의 재사용 및 유지 보수에 유리
응집도 : 하나의 모듈 내부에 존재하는 구성 요소들의 기능적 관련성
으로 응집도가 높은 모듈은 하나의 책임에 집중
하고 독립성이 높아져, 재사용 및 유지보수 용이
어떠한 클래스를 변경하고자 하는 이유는 한가지 뿐이여야 한다!
위에 그림을 보면 한 모듈이 다양한 기능을 다루고 있다
-> HttpClient : Network Connection, File Reader -> File Reader
위 경우 변경이 일어날 시 FTP Client도 수정하고 접근하는 FileReader 또한 변경해야 함
위 그림은 여러 기능들을 각각의 클래스(모듈)로 분리한 모습
//worst 절차지향적 예시
class Unit{
private String name;
private int speed;
public void attack() { }
public void move(){
if(name.equals("저글링")){
speed += 3
}else if(name.equals("탱크")){
if("탱크모드"){
speed = 0
} else{
speed = 10
}
}else if(name.equals("정찰기")){
speed = 15
충돌 = false
}
}
}
class 저글링 extends Unit{
public void move(){
this.speed += 3
}
}
class 탱크 extends Unit{
public void move(){
if("탱크모드"){
speed = 0
} else{
speed = 10
}
}
}
class 정찰기 extends Unit{
public void 정찰기(){
this.충돌 = false;
}
public void move(){
speed = 15
}
}
자신의 확장에는 열려 있고, 주변의 변화에 대해서는 닫혀 있어야 한다
상위 클래스
또는 인터페이스
를 중간에 둠으로써, 자신은 변화에 대해서는 페쇄적
이지만, 인터페이스는 외부의 변화에 대해서 확장을 개방
해 줄 수 있다
JDBC
, Mybatis, Hibernate 등, 자바에서는 Stream(input, output)에서 보임
직접 연결시 Db가 늘어날수록 Application 변경 사항이 늘어남
-> 이를 방지하기 위해 Interface를 둠
서브 타입은 언제나 자신의 기반(상위) 타입으로 교체 할 수 있어야 함
클라이언트는 자신이 사용하지 않는 메서드에 의존 관계를 맺으면 안된다
프로젝트 요구사항과 설계에 따라서 SRP
, ISP
선택
ex) 자동차는 자동차 길안내만 하면 되는데 위의 경우 상속받아 구현 시 다른 기능(하늘 길 안내, 지하철 노선...) 등 까지 상속받게 되어 그 기능들 또한 구현해야 되는 불편함이 생김
위 경우 인터페이스를 분리하여 자전거 내비는 자전거 길 안내 인터페이스만 구현함
자신보다 변하기 쉬운 것에 의존하지 말아야 한다
옷이라는 인터페이스를 통해 여름 옷, 봄옷, 가을 옷이 사람이 아닌 옷에 의존
Plain Old Java Object -> 순수한 자바 오브젝트 뜻함
특정 규약에 종속되지 않는다
특정 Library,Module에서 정의된 클래스를 상속받아 구현하지 않아도 됨. POJO가 되기 위해서는 외부의 의존성 두지 않고, 순수한 JAVA로 구성이 가능해야 함
특정 환경에 종속되지 않는다
만일 특정 비즈니스 로직을 처리 하는 부분에 외부 종속적인 http request, session 등 POJO를 위해한 것으로 간주. @Annotation 기반으로 설정하는 부분도 엄연히 POJO는 X
POJO를 지켜 나가기 위해 Spring,Hibernate
이용 -> 객체지향적 설계, Pojo 지향