03. Open/Close Principle

Wonseok Lee·2021년 12월 14일
0

Design Patterns

목록 보기
3/6
post-thumbnail

Open/Close Principle

한 줄 요약하면 class는 수정에 대해서는 닫혀있고, 확장에 대해서는 열려있어야 한다.로 요약할 수 있다.

개인적으로 가장 추상적으로 느껴져서 여러 책을 찾아보았고, 그나마 그 중에 아래의 재해석이 가장 마음에 들었다.

  • 기존의 코드를 변경하지 않으면서 새 기능을 추가할 수 있어야 한다.

예를 들어, 아래와 같이 주문(order)에 대하여 배송 방법에 따른 배송비를 합한 전체 금액(total price)을 반환하는 method를 지닌 class를 만들었다고 해보자.

모종의 사유로, 이제 비행기나 육로를 통한 배송이 아닌 배를 통한 배송 방법이 추가된다고 해보자.

이때, 아래 코드로 이 새로운 기능(배로 운송)을 대응하려면 double GetTotalPrice() method의 수정이 불가피하다.

class Order
{
private:
  size_t price_;
  size_t weight_;
  string shipping_;

public:
  double GetTotalPrice() const
  {
    if (shipping_ == "airplane")
    {
      return price_ + weight_ * 2.0;
    }
    else if (shipping == "ground")
    {
      return price_ + weight_ * 1.0;
    }
  }
};

반면, 아래와 같이 설계해놓았더라면(다른 챕터에서 언급할테지만 이는 stragedy pattern이다) 배로 배송하는 경우에 대하여 신규로 class 하나만 새로 만들어주면 될 뿐, Order class에는 아무런 수정이 필요하지 않게 된다.

이와 같이 신규 기능 추가 시 기존 코드의 수정을 줄이도록 하는 원칙이 Open/Close Principle의 핵심이라고 볼 수 있다.

class Order
{
private:
  size_t price_;
  size_t weight_;
  Shipping* shipping_;

public:
  double GetTotalPrice() const
  {
    return shipping_->GetCost(price_, weight_);
  }
}

class Shipping
{
public:
  virtual double GetCost(size_t price, size_t weight) const = 0;
};

class Airplane : public Shipping
{
public:
  double GetCost(size_t price, size_t weight) const
  {
    return price + weight * 2.0;
  }
};

class Ground : public Shipping
{
public:
  double GetCost(size_t price, size_t weight) const
  {
    return price + weight * 1.0;
  }
};

class Ship : public Shipping
{
public:
  double GetCost(size_t price, size_t weight) const
  {
    return price + weight * 1.5;
  }
};
profile
Pseudo-worker

0개의 댓글