매일 한줄 코딩

2주차 - 캡슐화란? 자바에서 캡슐화 하는 이유. 본문

IT서적 & 세미나/사내 세미나

2주차 - 캡슐화란? 자바에서 캡슐화 하는 이유.

ShipJH 2021. 12. 11. 21:38

앱 출시 후 서비스 하는 기간이 길어질수록 코드 1줄당 새롭게 개발하거나 변경되는 비용도 높아진다.

이미 출시된 서비스에 무언가를 바꿀때 미치는 영향도 때문에 소스를 다 뒤지는 시간이 길어지며, 대부분 그 시간을 할애한다.

그렇기 때문에 서비스하는 기간이 길어질수록 코드를 변경하는 비용은 높아지는 것이다.

그래서 우리는 코드를 추가,수정 할때 위치 혹은 영향도를 찾는 시간을 줄여야 한다.

그것을 자바의 대표적인 특징인 캡슐화로 어느정도 비용을 줄일 수 있다.

먼저, 캡슐화를 들어가기전에

커플링(결합도) 와 응집도에 대해 간단히 알아봐야 한다.

  • 커플링(결합도) 란?
  • 말그대로 A코드와 B코드가 서로 결합되어 있는 정도가 커서 A가 바뀌면 B에도 영향이 있는 경우에 결합도가 높다고 표현한다.
  • 응집도 란?
  • 결합도와 반대되는 것으로, 관련된 코드가 최대한 하나로 뭉쳐있는 정도이고, 이를 응집도가 높다고 표현한다.

💡그러므로, 개발의 좋은 방향성은, 결합도를 낮추고⬇️, 응집도를 높이는⬆️ 것이다.

캡슐화는 그런 응집도와 관련있다.

우리가 아는 캡슐화의 정의는 아래와 같다.

  • 캡슐화는 관련이 있는 변수와 함수를 하나의 클래스로 묶고 외부에서 쉽게 접근하지 못하도록 은닉하는 것.
  • 객체에 직접적인 접근을 막고 외부에서 내부의 정보에 직접접근하거나 변경할 수 없고,  객체가 제공하는 필드와 메소드를 통해서만 접근이 가능하도록 하는 것

소스로 표현해보자.

 

💡 ex) 사용자(Member)의 계정 만료일(expiredDate)을 가지고 여러 서비스에서 사용하는 경우.

A서비스에서..

// A service
public Response aService() {

...
		Member member = new Member();
		if (LocalDate.now().equals(member.getExpiredDate())){ 
			...
		}
...
}

B서비스에서..

// B service
public Response bService() {

...
		Member member = new Member();
		if (LocalDate.now().equals(member.getExpiredDate())){ 
			...
		}
...
}

이렇게

각각 오늘날짜로 만료일이라면 어떠한 행위를 하라 라는

만료일 == 오늘 일 경우라는 동일한 함수를 구현해서 쓰고있다.

여기서 만료일이면서, 10살 이하인 경우만으로 변경해달라고 한다면 우린 A와 B두가지에 또 getAge(); 를 하거나 하여 if문을 더 추가하는 등의 행위를 할 것이다.

예시는 A와 B 두가지로만 하였지만 실제 서비스가 길어지다보면 A,B,C,D,E.... 등등에서 동일하게 쓰고 있을 지 모른다.

그렇게되면 어느 하나의 서비스는 10살 이하인 경우가 누락되거나 등등의 경우가 생겨서

처음에는 같은 의미였지만 시간이 지남에따라 각각의 의미가 달라질수 있는 경우가 생긴다.

때문에 이것은 커플링(결합도)가 높다고 말할 수 있는 코딩이다.

 

💡 그렇다면 캡슐화를 이용하여 응집도를 높이는 건 어떻게하면 좋을까?

 

먼저 Member 클래스내에서 해당 기능을 제공해주는 메서드를 만들어 A, B가 그것을 이용하게끔 한다면

추후에 10살이하의 아이라는 조건이 추가되더라도 Member 클래스내에 기능을 제공해주는 메서드만 변경한다면 A,B 모두 동시에 적용이 된다.

public class Member {
	private String name;
	private int age;
	pirvate LocalDate expiredDate;

...

// getter.. setter ...
...

	public boolean isExpiredNow() {
		return LocalDate.now().equals(this.expiredDate);
	}
}

이렇게 쓰고 isExpiredNow() 함수를 A, B모두 if문에서 사용하였다면 ..

추후에 10살 아래의 유저들만 이라는 조건이 들어가더라도..

public class Member {
	private String name;
	private int age;
	pirvate LocalDate expiredDate;

...

// getter.. setter ...
...

	public boolean isExpiredNow() {
		return LocalDate.now().equals(this.expiredDate) && 10 > this.age;
	}
}

이렇게 변환되더라도 isExpiredNow() 를 쓰는 서비스들은 모두 다 변경되게 될 것이다.

이는 캡슐화를 통하여 응집도를 높인⬆️ 결과이다.

변경할곳이 Member객체안에 모여있어 추후에 수정시에도 비용이 떨어졌다고 볼 수 있다.

ps. 손코딩이라 오타 혹은 문법에 에러가 있을 수 있음.

Comments