본문 바로가기
카테고리 없음

[oop] 원시값을 포장하라!

by 손너잘 2021. 4. 20.

소트웍스 앤솔러지:소프트웨어 기술과 혁신에 관한 에세이 에는 원시값을 포장하라는 내용이 나온다.

왜 우리는 원시값을 포장해야하는걸까?

 

모두가 알고 있듯, 객체지향은 캡슐화, 추상화, 상속성, 다형성과 같은 특성을 가지고 있다. 그중에 원시값의 포장은 캡슐화와 매우 큰 연관성을 가지고 있다.

 

캡슐화에 관해서는 이곳 을 참조 바란다.

 

즉, 데이터와 그 로직을 한곳에 모아두라는 의미이다. 그렇게 해서 객체가 생성되면, 그 객체에는 생명이 생긴다.

단순한 데이터 덩어리에서 객체라는 하나의 유기체로 승격되는 것 이다.

 

public class Wallet {
   Card card;
   long cash;

   public void pay(long fee) {
       if(cash - fee < 0 ) {
           throw new IllegalStateException();
       }

       cash -= fee;
   }

}

예시를 만들기 위해 간단한 지갑 클래스를 생성했다. 지갑에는 카드와 현금이 들어있다.

혹자는 Wallet이라는 객체 안에 cash와 그에 대한 로직이 들어있기에 캡슐화가 만족되고 객체지향적이라고 말할 수 있다.

하지만 생각해보면 위에서 cash는 그냥 데이터 조가리일 뿐이다. Wallet이라는 클래가 cash라는 데이터를 대표해 주는가? 그렇지 않다.

객체가 cash라는 데이터를 대표해주지 못하기 때문에 cash는 단순한 데이터 조가리가 된다. 단지 Wallet안에 데이터 조가리를 컨트롤 하는 로직이 들어있을 뿐이다. (물론 시각에 따라서는 달라질 수 있다. 하지만 객체는 협력을 통해 자신의 존재를 입증한다는 사실을 생각해 보라).

 

따라서 위와 같은 코드는 단순히 데이터를  조작하는 절차지향적 설계가 된다. 그렇다면 한번 cash를 객체로 만들어서 활력을 불어 넣어보자.

public class Wallet {
   Card card;
   Cash cash;

   public void pay(long fee) {
      cash.pay(fee);
   }

}

public class Cash {
   long cash;

   public void pay(long fee) {
       if(cash - fee < 0 ) {
           throw new IllegalStateException();
       }

       cash -= fee;
   }

}

무엇이 달라졌는가? 객체간의 협력이 생겼다. Cash라는 객체는 데이터를 대표하며, 자신의 상태를 스스로 관리한다. cash라는 데이터가 객체로 승격되고 생명력이 생겼다.

 

또한 cash와 관련된 로직이 Cash 클래스 안으로 들어오면서 데이터와 로직이 하나로 뭉쳤다. 즉 응집력이 높아졌다.

이 뿐만인가? SOLID의 SRP와 OCP를 만족한다! 단순히 원시값을 포장했을 뿐인데 엄청난 변화가 발생했다.

 

따라서 원시값은 최대한 객체로 만들어 사용하는것이 좋다.

댓글