정의

어떤 목적을 이루기 위해서 여러가지 전략 중에서 한 가지를 선택하여 사용해야 하는 상황을 해결 하기 위한 디자인 패턴

OCP를 만족하면서 새로운 전략을 추가하고 싶을 때 사용 됨

 

OCP 가 지켜지지 않은 예제

CartForSongs

import java.util.ArrayList;
import java.util.List;

class Song {
    private String discountMode;
    private int price;
		public Song(String discountMode, int price){
			this.discountMode = discountMode;
			this.price = price;
		}
    public String getDiscountMode() {
        return discountMode;
    }
    public double getPrice() {
        return price;
    }
}

public class CartForSongs {
    List<Song> cart = new ArrayList<>();
    public double calculateTotalPrice(){
        double total = 0.0;
        for (Song song : cart) {
            if(song.getDiscountMode().equals("OnSale"))
                total = total + (song.getPrice()-0.1*song.getPrice());
            else if(song.getDiscountMode().equals("TodayEvent"))
                total = total + (song.getPrice()-0.3*song.getPrice());
            else if(song.getDiscountMode().equals("ChusukEvent"))
                total = total + (song.getPrice()-0.4*song.getPrice());
            else total = total + song.getPrice();
        }
        return total;
    }
    public void add(Song song) {
        cart.add(song);
    }
}
  • 해당 코드에 문제점 새로운 할인 모드가 추가되면 코드를 전체적으로 수정해야 한다.

1. 할인 정책 → 클래스 (변화의 단)

  • 변화의 단 식별 이후 클래스로 모델링

2. 포괄하는 개념 만들기

interface DiscountMode {
    public abstract double getDiscountRate();
}

class OnSale implements DiscountMode {
    @Override
    public double getDiscountRate() {
        return 0.1;
    }
}

class NoDiscount implements DiscountMode {
    @Override
    public double getDiscountRate() {
        return 0.0;
    }
}

class TodayEvent implements DiscountMode {
    @Override
    public double getDiscountRate() {
        return 0.3;
    }
}

public class Song {
    private double price;
    private String title;
    private DiscountMode discountMode;

    public Song(double price, String title) {
        this.price = price;
        this.title = title;
        this.discountMode = new NoDiscount();
    }
    public double getPrice(){
        return price - price*discountMode.getDiscountRate();
    }
    public void setDiscountMode(DiscountMode discountMode) {
        this.discountMode = discountMode;
    }
}
import java.util.ArrayList;
import java.util.List;

public class CartForSongs {
    private List<Song> cart = new ArrayList<>();
    public double calculateTotalPrice(){
        double total = 0.0;
        for (Song song : cart) total += song.getPrice();

        return 0.0;
    }
    public void add(Song song){
        cart.add(song);
    }
}
  • 새로운 할인 모드가 추가되어도 코드를 수정할 필요 없도록 개선됨

내용 요약

  • when: 어떤 목적을 이루기 위해서 여러가지 전략 중에서 한 가지를 선택하여 사용해야 하는 상황
  • how: OCP원칙이 지켜지게 끔 재설계
  • solve: 변화의 단 새로운 규칙이 추가되는 내용을 파악하여 abstract class or interface으로 정의
interface DiscountMode {
    public abstract double getDiscountRate();
}

class OnSale implements DiscountMode {
    @Override
    public double getDiscountRate() {
        return 0.1;
    }
}

class NoDiscount implements DiscountMode {
    @Override
    public double getDiscountRate() {
        return 0.0;
    }
}

class TodayEvent implements DiscountMode {
    @Override
    public double getDiscountRate() {
        return 0.3;
    }
}

'Development > Design Pattern' 카테고리의 다른 글

[Design Pattern] 싱글톤 패턴  (0) 2023.08.29

+ Recent posts