개발

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

Ridiss 2022. 4. 28. 08:46

객체란

- 기능으로 정의된 클래스 

- 기능은 메소드로 표현됨

- 단순히 변수만 있고 setter getter를 제공하는건 객체가 아니라 Data

 

캡슐화

- 데이터 + 관련기능 묶기

- 객체가 기능을 어떻게 구현했는지 외부에 감추는 것

  - 구현에 사용된 데이터의 상세 내요을 외부에 감춤

- 정보 은닉 의미 포함

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

 

*캡슐화하지 않았을 경우

if(acc.getMembership() == REGULAR && acc.getExpDate().isAfter(now())) {
	..정회원 기능제공
}

 5년이상 사용자 일부기능 정회원 혜택 1개월 무상제공기능이 추가될시

if(acc.getMembership() == REGULAR &&
	(
    	(acc.getServiceDate().isAfter(fiveYearAgo) && acc.getExpDate().isAfter(now())) ||
        (acc.getServiceDate().isBefore(fiveYearAgo) && addMonth(acc.getExpDate()).isAfter(now()))
	)
) {
	..정회원기능제공
}

이렇게 짜야할 가능성이 높음.

 

캡슐화하지 않으면

 

요구사항의 변화가 데이터 구조/사용에 변화를 발생시킴

Account -----------------------> 코드A

                                             ㄴ----> 코드B

                                             ㄴ----> 코드C                                        

                                       데이터를 사용하는 코드의 수정이 발생

요구사항 변경 예)

- 장기사용자에게 특정 기능실행 권한을 연장 (단 유효일자는 그대로 유지)

- 계정을 차단하면 모든 실행 권한 없음

- Date를 LocalDateTime으로 변경

 

캡슐화하면

- 기능을 제공하고 구현 상세를 감춤

if(acc.hasRegularPermission()) {
}

public class Account { //기능단위로 구현
    private Membership membership;
    private Date expDate;
    
    public boolean hasRegularPermission() {
    	return membership = REGULAR && expDate.isAfter(now())
    }
}

기능조건 변화시 내부 구현만 변경됨

if(acc.hasRegularPermission()) { //이건 변화가 없음
}

public class Account { 
    private Membership membership;
    private Date expDate;
    
    public boolean hasRegularPermission() { //해당 기능만 변경됨
    	return membership == REGULAR &&
        	( expDate.isAfter(now()) ||
            	(
                 serviceDate.isBefore(fiveYearAgo()) &&
                 addMonth(expDate).isAfter(now())
                )
			)
		);
    }
}

*캡슐화는 연쇄적인 변경 전파를 최소화

 

*캡슐화와 기능

- 캡슐화 시도 -> 기능에 대한 (의도) 이해를 높일수 있음.

 

*캡슐화를 위한 규칙

1. Tell, Don't Ask

 - 데이터를 달라고 하지말고 해달라고 하기 

// 멤버십데이터를 가져와서 확인을 하고있음 캡슐화(X)
if(acc.getMembership() == REGULAR) { 
	..정회원기능
}

// 멤버십인지 확인해달라고 하고있음 캡슐화(O)
if(acc.hasRegularPermission()) { 
	..정회원기능
}

 

2. Demeter's Law

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

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

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

 

acc.getExpDate().isAfter(now)     -------->   acc.isExpired()

Date date = acc.getExpDate();     -------->   acc.isValid(now)

date.isAfter(now);

 

*정리*

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

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

 

 

 

-참고-

인프런 최범균님 강의

'개발' 카테고리의 다른 글

REST API에 Under_Score(_)? Hyphen(-)?  (0) 2023.05.18
[Git] commit 되돌리기  (0) 2022.09.02
[객체지향프로그래밍] 다형성과 추상화  (0) 2022.05.06
[객체지향프로그래밍] 의존과 DI  (0) 2022.04.15
디자인패턴  (0) 2022.03.31