본문 바로가기

Programming/기초지식

[객체 지향] 캡슐화(Encapsulation)

반응형

캡슐화는 다음과 같다.

  • 데이터와 관련 기능(메서드)을 하나로 묶는다.
  • 객체가 어떻게 기능을 구현했는가를 외부에 감춘다.(구현 상세 내용 감춤)
  • 이를 통해 외부 영향 없이 객체 내부 구현 변경 가능

 

캡슐화를 하지 않으면 코드 작성 이후 추가적인 요구사항에 의한 데이터 구조/사용 변경에 유연하게 대처하기 어렵다.

예를 들어 날짜 표현 방식을 Date에서 LocalDateTime으로 변경하려면 기존 Date 클래스 메소드를 사용하는 모든 코드를 LocalDateTime 메소드 형식으로 교체해야 하기 때문에(연쇄적으로 변경이 전파된다) 프로젝트 규모가 클수록 부담스러운 일이 된다. 이런 문제 때문에 객체 지향에서는 데이터 접근을 객체에 속한 메서드를 통해서만 할 수 있도록 한다.

 

https://www.learncomputerscienceonline.com/object-oriented-programming/

 

캡슐화를 통해 기능을 제공하고 구현 상세를 감추는 방식으로 코드를 작성하면 유지보수가 편하다.

아래 코드는 Account 클래스에서 정회원을 구분하는 메서드 hasRegularPermission()을 Account 클래스 내부에 정의했다. 이 상태에서 메서드 사용 시 Account 메서드 생성자 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())
           )
         );
    }
}

// 캡슐화된 메소드 호출
if(acc.hasRegularPermission()) { ... }

 

또한 캡슐화를 통해 기능에 대한 이해(의도를 파악)를 높일 수 있다.

아래 코드는 캡슐화를 하지 않은, 사용자가 데이터를 직접 가져와서 코드를 구현하는 내용인데, 만약 코드를 처음 보는 개발자가 해당 코드를 본다면 getMembership() 메서드를 통해 데이터 값이 REGULAR인지 아닌지 검사하는 명확한 이유를 알기 어려울 것이다.

 

if(acc.getMembership() == REGULAR) { ... }

 

 

위 코드를 아래 코드로 캡슐화하여 구현하면 메서드 사용 의도를 명확히 알 수 있다.(메서드 이름 차이인 것 같지만)

 

public class Account {
	private Membership membership;
	private Date expDate;
    
    public boolean hasRegularPermission() {
    	return membership == REGULAR && expDate.isAfter(now())
    }
}

// 캡슐화된 메소드 호출
if(acc.hasRegularPermission()) { ... }

 

캡슐화의 규칙

 

Tell, Don't Ask

  • 데이터를 부탁하지 말고 해달라고 하자.
// Membership 데이터를 가져오는 메서드. 데이터를 달라고 한다.
if(acc.getMembership() == REGULAR) { ... }

// 데이터를 사용자가 원하는 값인지 어떤지 확인 해달라고 한다.
if(acc.hasRegularPermission()) { ... }

 

Demeter's Law

  • 메서드에서 생성한 객체의 메서드만 호출
  • 파라미터로 받은 객체의 메서드만 호출
  • 필드로 참조하는 객체의 메서드만 호출
// 권장하지 않는 방법. 메서드.메서드와 같이 연속해서 호출하는 것을 지양할 것.
acc.getExpDate.isAfter(now())
또는
Date date = acc.getExpDate();
date.isAfter(now());

// 메서드에서 생성한 객체의 메서드만 호출하자.
acc.isExpired();
또는
acc.isValie(now());

 

참조

https://www.inflearn.com/course/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%9E%85%EB%AC%B8/dashboard

 

객체 지향 프로그래밍 입문 - 인프런 | 강의

잘 하는 개발자가 되기 위해서는 유연한 코드를 작성할 줄 알아야합니다. 객체 지향을 이용해서 변경하기 좋은 유연한 코드를 만드는 방법을 알아보세요., 객체 지향 프로그래밍 입문 이번 '객

www.inflearn.com

 

반응형

'Programming > 기초지식' 카테고리의 다른 글

[객체 지향] 다형성과 추상화  (0) 2021.10.22
[객체 지향] 캡슐화 연습  (0) 2021.10.21
절차지향과 객체지향  (0) 2021.10.21
URI 그리고 URL  (0) 2021.09.03
Parameter와 Argument의 차이점  (0) 2021.08.25