ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디자인 원칙 - 변화하는 내용을 캡슐화
    Web 개발/디자인 패턴 2022. 12. 20. 11:49

    소프트웨어 설계에는 몇 가지 보편적인 원칙들이 있다.

     

    변화하는 내용을 캡슐화

    당신의 프로젝트에서 변경되는 부분들을 식별한 후 변하지 않는 부분들과 구분하세요.

     

    이 원칙의 가장 큰 목적은 변화로 인해 발생하는 결과를 최소화하는 것이다. 독립된 모듈에서 변경되는 프로그램의 일부를 따로 떼어내면 코드의 나머지 부분들을 역효과로부터 보호할 수 있을 뿐 만아니라 변경 사항들을 구현하고 테스트하는 데 걸리는 시간을 줄일 수 있다. 

     

    매서드 수준에서 의 캡슐화

    전자 상거래 웹사이트를 개발하고 있다고 가정해보자 코드 어딘가 세금을 포함한 주문의 총계를 계산하는 getOrderTotal메서드가 있다.

     

    이때 쉽게 미래에 세금과 관련한 코드를 변경해야 할지도 모른다는 것을 예측할 수 있다. 왜냐면 세율은 거주하는 국가,주,도시에 따라 다르고, 시간이 흘러 새로운 법률이나 규정이 나와 코드를 변경해야 할 수도 있기 때문이다. 그러면  getOrderTotal메서드를 아주 자주 변경해야 할 수도 있다.

     

     

    수정 전: 세금 계산 코드가 메서드의 나머지 코드와 뒤섞여 있다.

    import { Order } from "./order";
    
    export class OrderService {
      public getOrderTotal(order: Order) {
        let total = 0;
    
        order.lineItems.forEach((item) => {
          total += item.price * item.quantity;
        });
    
        if (order.country == "US") {
          total += total * 0.07; //US sale tax
        } else if (order.country == "EU") {
          total += total * 0.2; //European VAT
        }
    
        return total;
      }
    }

    그러나 위 코드의 메서드 이름에서도 알 수 있듯이 세금이 계산되는 방법에는 아무관심이 없다.

    -> 세금 계산 로직을 별도의 메서드로 추출하여 원래 메서드로부터 숨길 수 있다.

     

    수정후: 지정된 메서드를 호출함으로써 세율을 구할 수 있다.

    import { Order } from "./order";
    
    export class OrderService {
      public getOrderTotal(order: Order) {
        let total = 0;
    
        order.lineItems.forEach((item) => {
          total += item.price * item.quantity;
        });
    
        total += total * this.getTaxRate(order.country);
    
        return total;
      }
    
      public getTaxRate(country: string) {
        if (country == "US") {
          return 0.07; //US sale tax
        } else if (country == "EU") {
          return 0.2; //European VAT
        } else {
          return 0;
        }
      }
    }

    이제 세금 관련 변경 사항들은 단일 메서드 내에서 격리된다. 또 세금 계산 로직이 너무 복잡해지면 그것을 별도의 클래스로 옮기기도 쉬워졌다.

     

    클래스 수준에서의 캡슐화

    시간이 흐르면서 이전에는 간단한 작업을 수행했던 메서드에 점점 더 많은 책임이 추가될 수 있다. 이렇게 추가된 행동들은 고유의 도우미 필드와 메서드를 동반하곤하는데, 이는 결국 이 모든 것을 포함하는 클래스의 기본적인 책임을 모호하게 만든다. 그래서 그 모든것을 새 클래스로 추출하면 코드는 훨씬 명확하고 간단해진다.

     

    수정 전:Order(주문)클래스의 세금 계산

    Order 클래스의 객체들이 모든 세금 관련 작업을 해당 작업만 수행하는 특수 객체에 위임한다.

     

     

    수정 후 : 세금 계산은 Order(주문)클래스로부터 숨겨진다.

     

    function getOrderTotal(lineItems: LineItems){
    let total = 0
    
    lineItems.forEach((item) => {
    	subtotal = item.price * item.quantity
        total += subtotal * taxCalc.getTaxRate(country,state,item,product)
    	});
        
     return total;
    }

     

     

    댓글

Designed by Tistory.