WEB/JAVA

객체 지향 프로그래밍 - 객체, 캡슐화

 인프런 객체 지향 프로그래밍 입문 - 최범균를 공부하며 적은필기 노트입니다.

 

직접 실전에서 Java를 쓰게 되면서 객체 지향 프로그래밍에 중요성이 뼈를 강타했다... 공부하자!

 

"Software maintenance is not keep it working like before it is keep being useful in a changing world" - Jessica Kerr

유지보수는 그대로를 관리하는 것이 아니라 유용하게 변경하는 것이다.

그러므로 분석과 수정이 빠르게 되어야 한다.

 

비용과 변화

낮은 비용으로 변화할 수 있어야 한다.

1. 패러다임

  객체 지향, 함수형, 리액티브 등

2. 코드, 설계, 아키텍처

  DRY, TDD, SOLID, DDD, ...

  클린 아키텍처, MSA, ...

3. 업무 프로세스/문화

  애자일, DevOps, ...

+

객체지향이 비용을 낮추는 방법

캡슐화 + 다형성(추상화)

 

객체

절차 지향 vs 객체 지향 : 절차 지향

절차 지향은 시간이 갈수록 복잡해지고 수정이 어려워진다. 

-> 데이터가 많은 곳에서 사용하게 되면 복잡해지고 정확성이 떨어진다.

 

객체지향은 각각의 객체가 데이터와 프로시저를 포함하고 있어 다른 객체가 해당 데이터에 접근하지 못하도록 한다.

-> 프로시저를 호출하여 연결하게 한다.

 

객체의 핵심 -> 기능 제공

 객체는 제공하는 기능으로 정의 -> 내부적으로 가진 데이터로 정의하지 않는다.

 

이러한 객체와 객체가 상호 작용하는 것을 메시지를 주고 받는다고 표현합니다.

 -> 메서드를 호출하는 메시지, 리턴 메시지, 익셉션 메시지

 

캡슐화

캡슐화만 잘해도,,, 좋은 코드를 만들 가능성을 높힌다...

 

- 데이터 + 관련 기능 묶기

- 객체가 기능을 어떻게 구현했는지 외부에 감춘다. ( 데이터 상세 내용을 외부에 감춤)

- 정보 은닉 의미 포함

- 외부에 영향 없이 객체 내부 구현 변경 가능

 


// 이런 기능이 있다면
if(acc.getMembership() == REGULAR && acc.getExpDate().isAfter(now())) {
	...정회원 기능
}


// 요구사항이 변경되면서 발생할 수 있는 문제 
if(acc.getMembership() == REGULAR && 
 (
   (acc.getServiceDate().isAfter(fiveYearAgo) && acc.getExpDate().isAfter(now())) ||
     조건 || 조건 || 조건  . . .)
 )
 {
   ...정회원 기능
 }

요구 사항이 변화가 발생하여 데이터 구조/사용에 변화가 생김 -> 수정이 연쇄적으로 발생된다.(절차지향 방식) 

 

 

캡슐화를 하여 해결한 방법

if(acc.hasRegularPermission()) {
  ... 정회원 기능
  }
  
  
  pulbic class Account{
    private Membership memvership;
    private Date expDate;
    
    // 회원 관련된 기능
    public boolean hasRegularPermission(){
     return membership == REGULAR && expDate.isAfter(now())
   }

이런식으로 구조를 잡으면 요구사항이 변화가 생겨도 캡슐화한 회원 관련된 기능 메소드만 수정해주면 된다.

 

- 연쇄적인 변경 전파를 최소화할 수 있어 캡슐화된 기능을 사용하는 코드 영향을 최소화할 수 있다.

- 그리고 캡슐화를 시도하게 되면 기능에 대한 이해를 높일 수 있다.

- 캡슐화를 위한 규칙 

   Tell, Don't Ask 데이터 달라 하지 말고 해달라고 하기 --> 캡슐화 가능성 높아짐

if(acc.getMembership() == REGULAR(){
	정회원 기능
 }
 
 // --->
 
 if(acc.hasRegularPermission()){
 	정회원 기능
 }

캡슐화를 위한 규칙

- Demeter's Law

 메서드에서 생성한 객체의 메서드만 호출

 파라미터로 받은 객체의 메서드만 호출

 필드로 참조하는 객체의 메서드만 호출

 

acc.getExpDate().isAfter(now)   ->  acc.isExpried()
Date date = acc.getExpdate();   ->  acc.isValid(now)
date.isAter(now);  

 

정리

캡슐화 : 기능의 구현을 외부에 감춤

캡슐화를 통해 기능을 사용하는 코드에 영향을 주지 않고(또는 최소화) 내부 구현을 변경할 수 있는 유연함