본문 바로가기
언어/JAVA

[JAVA] 캡슐화

by steadyMan 2022. 5. 26.

객체 지향언어의 특징인 캡슐화를 고려한 로직을 작성하면 기능수정이 발생할때 사이드이펙트를 최소화 하며  

로직수정의 유연함을 보유할 수 있다. 이는 다양한 이점을 가진다.

한 번에 캡슐화잘된 코드를 작성하기란 불가능 하겠지만 요소들을 잘 기억하여 다시 살펴볼때 수정할수 있도록 공부하자!

 

개인적인 학습의 정리글입니다. 

 

먼저 캡슐화의 특성을 보면

 1. 데이터 + 관련 기능을 하나의 클래스에 담기 

    - 관련있는 데이터와 기능을 하나의 클래스에 필드, 메서드로 작성한다. 

2. 객체가 기능을 어떻게 구현했는지 외부로부터 감추기 

    - 기능을 객체의 메소드안에 작성하여 메소드 호출로서 기능을 사용할 수 있도록 한다. 

3.  정보은닉

    - 위의 특성과 비슷하며 객체에 대한 구체적인 정보를 노출시키지 않도록 한다. 

 

다음은 캡슐화를 진행과정에 대해 정리했다.

캡슐화 이전

if(acc.getAuth() == ADMIN && acc.getExpDate < 3) {
	//정회원 기능 제공
}

권한 및 만료일을 비교하여 어드민 기능 제공하는 로직이다. 현재에서 조건의 변경이 생기면 어떻게 될까? 

if(acc.getAuth() == ADMIN && 
    (acc.getExpDate < 3 && acc.getPaymentWay() != null) ||
    (acc.getTotalPrice() > 30000 && acc.getAge > 20)
  )	{
		//정회원 기능 제공
}

조건이 변경되기 전에도 주석이 있지 않다면 왜 해당 조건들을 확인하는지 의도를 알 수 없지만 조건이 추가되며 

더더욱 알기가 힘들어졌다. 

더 큰 문제는 이런 로직이 한군데가 아닌 여러코드에 있다고 한다면 변경비용이 상당히 발생한다. 

캡슐화 진행 

public class Account {
    private String auth;
    private int age;
    private Date expDate;
    ...
    
    public boolean hasAdminPermission() {
    	return acc.getAuth() == ADMIN && 
		       (acc.getExpDate < 3 && acc.getPaymentWay() != null) ||
		       (acc.getTotalPrice() > 30000 && acc.getAge > 20)
    }
}

Account 클래스에 기존의 로직을 수행하는 hasAdminPermission이란 메소드를 생성한다.

 

기존의 분산된 로직에서 해당 메소드를 공통으로 사용하는 상황이된다면 내부 로직이 변경되도 사용하는 쪽에선

변경사항이 없고 사이드이펙트도 최소화 할 수 있다.

캡슐화로 인한 변경

if(hasAdminPermission()) {
	...
}

기존에 구현만 있어서 조건을 확인하고 의도를 파악하는 시간이 필요했다면

현재는 메소드의 이름만 보고 의도파악이 가능하다. 

캡슐화를 위한 규칙 

1. 데이터를 가져와서 비교하지말고 결과를 가져오자 

acc 객체에서 auth데이터를 가져와서 비교하는것이 아닌 결과를 리턴하는 메소드를 실행하여 결과를 받아온다. 

if(acc.getAuth() == "ADMIN") {
	...
}

//==아래와 같이 변경==//

if(acc.hasAdminPermission()) {
	...
}

2. 하나의 객체에서 로직 처리하기 

  메서드에서 생성했거나, 파라미터로 받은 객체이거나, 필드를 참조하는 객체의 메소드만 호출하여 

  로직을 처리 하도록 하자.

payment pay = acc.getPayMent();
pay.isPay(pay);

//==아래와 같이 변경==//
acc.ispayment();

정리

캡슐화란 기능의 구현을 외부로부터 감추어 제공하며 캡슐화 과정중에 구현의 의도를 파악할 수 있고

기능을 사용하는 쪽에서도 빠른 의도 파악으로 효용성 증대를 기대할 수 있으며 

캡슐화를 통하여 기능을 사용하는 코드에 대한 영향을 최소화 하며 내부 구현을 변경할 수 있는 유연함이 발생한다.

댓글