OOP의 4대원칙을 중 캡슐화를 배운 내용을 풀어볼까 합니다.
위키피디아의 정의를 보면,
캡슐화(영어: encapsulation)는 객체 지향 프로그래밍에서 다음 2가지 측면이 있다:
객체의 속성(data fields)과 행위(메서드, methods)를 하나로 묶고,
실제 구현 내용 일부를 내부에 감추어 은닉한다.
내가 자바에서 클래스를 만들 때, 그 모습아닌가?
일단 짝수홀수 구분하는 코드 만들어보자.
public class EvenOdd {
private int num = 10;
public EvenOdd(int num) {
this.num = num;
}
public void getEven() {
if (num % 2 == 0) {
System.out.println("짝수입니다");
}
}
public void getOdd() {
if (num % 2 != 0) {
System.out.println("홀수입니다");
}
}
}
클래스를 만들 때 필드변수, 생성자, 메서드들을 넣는다. 그것이 바로 객체의 속성과 행위를 클래스라는 캡슐에 넣어둔 것이다.
그렇지만 이렇게 날 것으로 정리할 수는 없다.
캡슐화는 데이터와 데이터를 처리하는 행위를 묶어서 외부에는 그 행위를 보여주지 않는 것이다.
데이터와 데이터를 처리하는 행위를 묶은 것은 알겠는데, 외부에는 그 행위를 노출시키지 않는다는 것은 접근제어자를 잘 활용하라는 의미인가?
나는 자율성과 관련된 부분을 생각해 보았다.
좋은 객체지향은 자율성을 갖은 객체들이 서로 협력하는 것이다. 데이터를 객체에게 꺼내와서 처리하는것이 아니라, 객체에게 처리를 요청해야 하는 것이다.
이렇게 공부하다보니 캡슐화 느낌이 딱 오기 시작했다. 많은 블로그들을 보면서 캡슐화는 접근제어를 잘 활용하여 외부에 알리고 싶지 않는 것들을 감추는 것으로 생각 해왔다. 하지만 그건 전부가 아니었다.
애초에 자율성을 보장하여 객체에게 요청을 보낸다면 객체가 갖은 행위를 외부에 보이게 할 필요가 없다.
글로만 보면 잘 이해가 되지 않아 코드를 짜보았다.
다이소에서 1000원짜리 상품(객쳬)을 가져와서 10%할인 로직 후에 다른 로직으로 넘긴다는 상황이다.
class Goods {
int price = 1000;
...
public int getDiscountedPrice() {
return price * 0.9;
}
}
public void diff(Goods goods) {
double discountedPrice = goods.getDiscountedPrice();
var(discountedPrice);
}
10% 할인하는 로직, 그 로직을 활용하는 diff() 로직 모두 Goods 객체 내에서 처리된다. 즉, 요청을 하면 자율성을 갖은 객체가 알아서 하도록 설계하고 만들어야 한다. 만약 할인율이 5%로 바뀐다고 한다면, 자연스럽게 getDiscountedPrice() 로직을 수행하면 되는 것이다.
이것이 캡슐화의 두가지 장점이다.
코드의 중복을 피할 수 있고, 데이터를 처리하는 동작 방식을 외부에 노출시킬 필요가 없다는 것이다.
이렇게 공부한 순간 캡슐화의 강력함을 깨달아 버렸다.