๐Ÿ“• [Object] 2์žฅ. ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๋ฐ•์ƒ๋ฏผยท2024๋…„ 2์›” 24์ผ

Book

๋ชฉ๋ก ๋ณด๊ธฐ
8/22
post-thumbnail

โญ๏ธ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ–ฅํ•ด

๐Ÿ“Œ ํ˜‘๋ ฅ, ๊ฐ์ฒด, ํด๋ž˜์Šค

์ง„์ •ํ•œ ๊ฐ์ฒด์ง€ํ–ฅ ํŒจ๋Ÿฌ๋‹ค์ž„์œผ๋กœ์˜ ์ „ํ™˜์€ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด์— ์ดˆ์ ์„ ๋งž์ถœ ๋•Œ์—๋งŒ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๋Š” ๋™์•ˆ ๋‹ค์Œ์˜ ๋‘ ๊ฐ€์ง€์— ์ง‘์ค‘ํ•ด์•ผ ํ•œ๋‹ค.

  • ์–ด๋–ค ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•œ์ง€๋ฅผ ๊ณ ๋ฏผํ•˜๊ธฐ ์ „์— ์–ด๋–ค ๊ฐ์ฒด๋“ค์ด ํ•„์š”ํ•œ์ง€ ๊ณ ๋ฏผํ•˜๋ผ.
    - ํด๋ž˜์Šค๋Š” ๊ณตํ†ต์ ์ธ ์ƒํƒœ์™€ ํ–‰๋™์„ ๊ณต์œ ํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ์ถ”์ƒํ™”ํ•œ ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค์˜ ์œค๊ณฝ์„ ์žก๊ธฐ ์œ„ํ•ด์„œ๋Š”์–ด๋–ค ๊ฐ์ฒด๋“ค์ด ์–ด๋–ค ์ƒํƒœ์™€ ํ–‰๋™์„ ๊ฐ€์ง€๋Š”์ง€ ๋จผ์ € ๊ฒฐ์ •ํ•ด์•ผ ํ•œ๋‹ค. ๊ฐ์ฒด๋ฅผ ์ค‘์‹ฌ์— ๋‘๋Š” ์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ ์‹ค์ฒด๋ฅผ ๋‹จ์ˆœํ•˜๊ณ  ๊น”๋”ํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.
  • **๊ฐ์ฒด๋ฅผ ๋…๋ฆฝ์ ์ธ ์กด์žฌ๊ฐ€ ์•„๋‹ˆ๋ผ, ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์œ„ํ•ด ํ˜‘๋ ฅํ•˜๋Š” ๊ณต๋™์ฒด์˜ ์ผ์›์œผ๋กœ ๋ด์•ผ ํ•œ๋‹ค.
    - ๊ฐ์ฒด๋Š” ํ™€๋กœ ์กด์žฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ๋„์›€์„ ์ฃผ๊ฑฐ๋‚˜ ์˜์กดํ•˜๋ฉด์„œ ์‚ด์•„๊ฐ€๋Š” ํ˜‘๋ ฅ์ ์ธ ์กด์žฌ์ด๋‹ค. ๊ฐ์ฒด๋ฅผ ํ˜‘๋ ฅํ•˜๋Š” ๊ณต๋™์ฒด์˜ ์ผ์›์œผ๋กœ ๋ฐ”๋ผ๋ณด๋Š” ๊ฒƒ์€ ์„ค๊ณ„๋ฅผ ์œ ์—ฐํ•˜๊ณ  ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

๐Ÿ“Œ ๋„๋ฉ”์ธ์˜ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅด๋Š” ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ

๋„๋ฉ”์ธ(domain)

  • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ถ„์•ผ

๊ฐ์ฒด์ง€ํ–ฅ ํŒจ๋Ÿฌ๋‹ค์ž„์ด ๊ฐ•๋ ฅํ•œ ์ด์œ 

  • ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ถ„์„ํ•˜๋Š” ์ดˆ๊ธฐ ๋‹จ๊ณ„๋ถ€ํ„ฐ, ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๊นŒ์ง€ ๊ฐ์ฒด๋ผ๋Š” ๋™์ผํ•œ ์ถ”์ƒํ™” ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
    ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐน์ฒด๋ผ๋Š” ๋™์ผํ•œ ๊ด€์ ์—์„œ ๋ณด๊ธฐ ๋•Œ๋ฌธ์— ๋„๋ฉ”์ธ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐœ๋…๋“ค์ด ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฐ์ฒด์™€ ํด๋ž˜์Šค๋กœ ๋งค๋„๋Ÿฝ๊ฒŒ ์—ฐ๊ฒฐ๋œ๋‹ค.


์ผ๋ฐ˜์ ์œผ๋กœ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜์˜ ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์—์„œ๋Š” ๋„๋ฉ”์ธ ๊ฐœ๋…์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Class๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
Class์˜ ์ด๋ฆ„์€ ๋Œ€์‘๋˜๋Š” ๋„๋ฉ”์ธ ๊ฐœ๋…์˜ ์ด๋ฆ„๊ณผ ๋™์ผํ•˜๊ฒŒ ํ•˜๊ฑฐ๋‚˜ ์ ์–ด๋„ ์œ ์‚ฌํ•ด์•ผ ํ•œ๋‹ค.
Class ์‚ฌ์ด์˜ ๊ด€๊ณ„๋„ ์ตœ๋Œ€ํ•œ ๋„๋ฉ”์ธ ๊ฐœ๋… ์‚ฌ์ด์— ๋งบ์–ด์ง„ ๊ด€๊ณ„์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ณ , ์˜ˆ์ƒํ•˜๊ธฐ ์‰ฌ์›Œ์ง„๋‹ค.

๋”ฐ๋ผ์„œ Class ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋„๋ฉ”์ธ ๋ชจ๋ธ๊ณผ ์œ ์‚ฌํ•œ ํ˜•ํƒœ๋ฅผ ๋ณด์ด๊ฒŒ ๋œ๋‹ค. ๋‹ค์Œ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ๋ง์ด๋‹ค.

๐Ÿ“Œ ์ž์œจ์ ์ด ๊ฐ์ฒด

๊ฐ์ฒด์˜ 2๊ฐ€์ง€ ์ค‘์š”ํ•œ ์‚ฌ์‹ค

  • ๊ฐ์ฒด๋Š” ์ƒํƒœ(state)์™€ ํ–‰๋™(behavior)์„ ํ•จ๊ป˜ ๊ฐ€์ง€๋Š” ๋ณตํ•ฉ์ ์ธ ์กด์žฌ์ด๋‹ค.
  • ๊ฐ์ฒด๋Š” ์Šค์Šค๋กœ ํŒ๋‹จํ•˜๊ณ , ํ–‰๋™ํ•˜๋Š” ์ž์œจ์ ์ธ ์กด์žฌ์ด๋‹ค.

๊ฐ์ฒด์ง€ํ–ฅ ํŒจ๋Ÿฌ๋‹ค์ž„์—์„œ๋Š” ๊ฐ์ฒด๋ผ๋Š” ๋‹จ์œ„ ์•ˆ์— ๋ฐ์ดํ„ฐ์™€ ๊ธฐ๋Šฅ์„ ํ•œ ๋ฉ์–ด๋ฆฌ๋กœ ๋ฌถ์Œ์œผ๋กœ์จ ์บก์Аํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋“ค์€ ์ƒํƒœ์™€ ํ–‰๋™์„ ์บก์Аํ™”ํ•˜๋Š” ๊ฒƒ์—์„œ ํ•œ ๊ฑธ์Œ ๋” ๋‚˜์•„๊ฐ€ ์™ธ๋ถ€์—์„œ์˜ ์ ‘๊ทผ์„ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋Š” ์ ‘๊ทผ ์ œ์–ด(access control) ๋ฉ”์ปค๋‹ˆ์ฆ˜๋„ ํ•จ๊ป˜ ์ œ๊ณตํ•œ๋‹ค.
๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์—์„œ๋Š” public, protected, private ์™€ ๊ฐ™์€ ์ ‘๊ทผ ์ˆ˜์ •์ž๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์™œ ๊ฐ์ฒด ๋‚ด๋ถ€์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ํ†ต์ œํ• ๊นŒ?
๋ฐ”๋กœ ๊ฐ์ฒด๋ฅผ ์ž์œจ์ ์ธ ์กด์žฌ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋‹ค. ๊ฐ์ฒด์ง€ํ–ฅ์˜ ํ•ต์‹ฌ์€ ์Šค์Šค๋กœ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ํŒ๋‹จํ•˜๊ณ , ํ–‰๋™ํ•˜๋Š” ์ž์œจ์ ์ธ ๊ฐ์ฒด๋“ค์˜ ๊ณต๋™์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐ์ฒด๊ฐ€ ์ž์œจ์ ์ธ ์กด์žฌ๋กœ ์„œ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์™ธ๋ถ€์˜ ๊ฐ„์„ญ์„ ์ตœ์†Œํ™”ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด ๋‚ด๋ถ€์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ํ†ต์ œํ•œ๋‹ค.

์™ธ๋ถ€์—์„œ ๊ฐ์ฒด์˜ ๊ฒฐ์ •์— ์ง์ ‘์ ์œผ๋กœ ๊ฐœ์ž…ํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค. ๊ฐ์ฒด์—๊ฒŒ ์š”์ฒญ๋งŒ ํ•˜๊ณ , ์Šค์Šค๋กœ ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์„ ๊ฒฝ์ฒญํ•˜๋„๋ก ํ•ด์•ผํ•œ๋‹ค.


์บก์Аํ™”์™€ ์ ‘๊ทผ ์ œ์–ด๋Š” ๊ฐ์ฒด๋ฅผ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆˆ๋‹ค.

  • ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„: public interface
  • ์™ธ๋ถ€์—์„œ๋Š” ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ , ์˜ค์ง ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„: implementatin(๊ตฌํ˜„)

์ผ๋ฐ˜์ ์œผ๋กœ Java์˜ ๊ฒฝ์šฐ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์˜ ๊ฐ€์‹œ์„ฑ์€ private์ด๊ณ , ์™ธ๋ถ€์— ์ œ๊ณตํ•ด์•ผ ํ•  ๋ฉ”์„œ๋“œ๋Š” public์ด๋‹ค.
public interface์—๋Š” public์œผ๋กœ ์ง€์ •๋œ ๋ฉ”์„œ๋“œ๋งŒ ํฌํ•จ๋œ๋‹ค.
๊ทธ ์™ธ์˜ private ๋ฉ”์„œ๋“œ, ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋Š” implementation์— ํ•ด๋‹นํ•œ๋‹ค.

๐Ÿ“Œ ํ˜‘๋ ฅํ•˜๋Š” ๊ฐ์ฒด๋“ค์˜ ๊ณต๋™์ฒด

Screening(์ƒ์˜), Money(๊ธˆ์•ก), Movie(์˜ํ™”), Reservation(์˜ˆ์•ฝ) ํด๋ž˜์Šค๋ฅผ ๋ณด์—ฌ์ค„ ๊ฒƒ์ด๋‹ค. ์ด๋•Œ ์ฝ”๋“œ๋ฅผ ๋ณผ ๋•Œ ์˜ํ™” ์˜ˆ๋งค๋ผ๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ด๋ค„์ง€๋Š” ์ƒํ˜ธ์ž‘์šฉ์„ ์œ ์˜ํ•ด์„œ ์ง€์ผœ๋ณด์ž.

Screening(์ƒ์˜)

public class Screening {
    private Movie movie;

    public Reservation reserve(Customer customer, int audienceCount) {
        return new Reservation(customer, this, calculateFee(audienceCount),
                audienceCount);
    }

    private Money calculateFee(int audienceCount) {
        return movie.calculateMovieFee(this).times(audienceCount);
    }
}

Money(๊ธˆ์•ก)

public class Money {
    public static final Money ZERO = Money.wons(0);

    private final BigDecimal amount;

    public static Money wons(long amount) {
        return new Money(BigDecimal.valueOf(amount));
    }

    public static Money wons(double amount) {
        return new Money(BigDecimal.valueOf(amount));
    }

    Money(BigDecimal amount) {
        this.amount = amount;
    }

    public Money plus(Money amount) {
        return new Money(this.amount.add(amount.amount));
    }

    public Money minus(Money amount) {
        return new Money(this.amount.subtract(amount.amount));
    }

    public Money times(double percent) {
        return new Money(this.amount.multiply(BigDecimal.valueOf(percent)));
    }

    public boolean isLessThan(Money other) {
        return amount.compareTo(other.amount) < 0;
    }

    public boolean isGreaterThanOrEqual(Money other) {
        return amount.compareTo(other.amount) >= 0;
    }
}

Reservation(์˜ˆ์•ฝ)

public class Reservation {
    private Customer customer;
    private Screening Screening;
    private Money fee;
    private int audienceCount;

    public Reservation(Customer customer, Screening Screening, Money fee, int audienceCount) {
        this.customer = customer;
        this.Screening = Screening;
        this.fee = fee;
        this.audienceCount = audienceCount;
    }
}

์˜ํ™” ์˜ˆ๋งค๋ผ๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ด๋ค„์ง€๋Š” ์ƒํ˜ธ์ž‘์šฉ์„ ๋ณด์•˜๋Š”๊ฐ€?
์ด๊ฒƒ์„ ํ˜‘๋ ฅ(Collaboration) ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•  ๋•Œ๋Š” ๋จผ์ € ํ˜‘๋ ฅ์˜ ๊ด€์ ์—์„œ ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•œ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ , ๊ฐ์ฒด๋“ค์˜ ๊ณตํ†ต ์ƒํƒœ์™€ ํ–‰์œ„๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

โœ”๏ธŽ ํ˜‘๋ ฅ์— ๊ด€ํ•œ ์งง์€ ์ด์•ผ๊ธฐ

๊ฐ์ฒด๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ์ธํ„ฐํŽ˜์ด์Šค์— ๊ณต๊ฐœ๋œ ํ–‰๋™์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์š”์ฒญ(request) ํ•  ์ˆ˜ ์žˆ๋‹ค. ์š”์ฒญ์„ ๋ฐ›์€ ๊ฐ์ฒด๋Š” ์ž์œจ์ ์ธ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•œ ํ›„ ์‘๋‹ต(response)ํ•œ๋‹ค.

๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†ก(send a message)ํ•˜๋Š” ๊ฒƒ ๋ฟ์ด๋‹ค.
๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•œ ๊ฐ์ฒด๋Š” ์Šค์Šค๋กœ์˜ ๊ฒฐ์ •์— ๋”ฐ๋ผ ์ž์œจ์ ์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•  ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•œ๋‹ค.

์ด์ฒ˜๋Ÿผ ์ˆ˜์‹ ๋œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ž์‹ ๋งŒ์˜ ๋ฐฉ๋ฒ•์„ ๋ฉ”์„œ๋“œ(method)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

์œ„์—์„œ ์†Œ๊ฐœํ–ˆ๋˜ ์ฝ”๋“œ์˜ ์ผ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๋ณด์ž.

public class Screening {
    private Money calculateFee(int audienceCount) {
        return movie.calculateMovieFee(this).times(audienceCount);
    }
}

์ด ์ฝ”๋“œ์˜ calculateFee ๋ฉ”์„œ๋“œ๋ฅผ ์„ค๋ช…ํ•  ๋•Œ ์–ด๋–ป๊ฒŒ ๋งํ•  ๊ฒƒ์ธ๊ฐ€?

  1. Screening์ด Movie์˜ calculateMovieFee '๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค'
  2. Screening์ด Movie์—๊ฒŒ calculateMovieFee '๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•œ๋‹ค'

์ •๋‹ต์€ 2๋ฒˆ์ด๋‹ค.
์‚ฌ์‹ค Screening์€ Movie ์•ˆ์— calculateMovieFee ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.
๋‹จ์ง€, Movie๊ฐ€ calculateMovieFee ๋ฉ”์‹œ์ง€์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ฏฟ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•  ๋ฟ์ด๋‹ค.

๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์€ Movie๋Š” ์Šค์Šค๋กœ ์ ์ ˆํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ํƒํ•œ๋‹ค.

โญ๏ธ ํ• ์ธ ์š”๊ธˆ ๊ตฌํ•˜๊ธฐ

๐Ÿ“Œ ํ• ์ธ ์š”๊ธˆ ๊ณ„์‚ฐ์„ ์œ„ํ•œ ํ˜‘๋ ฅ ์‹œ์ž‘ํ•˜๊ธฐ

Movie

public Movie(String title, Duration runningTime, Money fee, DiscountPolicy discountPolicy) {
    this.title = title;
    this.runningTime = runningTime;
    this.fee = fee;
    this.discountPolicy = discountPolicy;
}

Movie์˜ ์ƒ์„ฑ์ž๋ฅผ ์ž˜ ์‚ดํŽด๋ณด์ž.

๋ถ„๋ช… ํ• ์ธ ์ „๋žต์„ ๋ฐ›๊ณ  ์žˆ๊ธด ํ•˜์ง€๋งŒ, ์–ด๋– ํ•œ ํ• ์ธ ์ „๋žต์„ ์‚ฌ์šฉํ• ์ง€ ๋ช…์‹œ๊ฐ€ ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค.
์ด ์ฝ”๋“œ์—๋Š” ๊ฐ์ฒด์ง€ํ–ฅ์—์„œ ์ค‘์š”ํ•œ ๊ฐœ๋… ๋‘๊ฐ€์ง€๊ฐ€ ์ˆจ๊ฒจ์ ธ์žˆ๋Š”๋ฐ,
ํ•˜๋‚˜๋Š” ์ƒ์†, ํ•˜๋‚˜๋Š” ๋‹คํ˜•์„ฑ์ด๋‹ค. ๊ทธ ๊ธฐ๋ฐ˜์—๋Š” ์ถ”์ƒํ™”์˜ ์›๋ฆฌ๊ฐ€ ์ˆจ๊ฒจ์ ธ ์žˆ๋‹ค.

DiscountPolicy

public abstract class DiscountPolicy {
    private List<DiscountCondition> conditions = new ArrayList<>();

    public DiscountPolicy(DiscountCondition ... conditions) {
        this.conditions = Arrays.asList(conditions);
    }

    public Money calculateDisCountAmount(Screening screening) {
        for (DiscountCondition each : conditions) {
            if (each.isSatisfiedBy(screening)) {
                return getDiscountAmount(screening);
            }
        }

        return Money.ZERO;
    }

    abstract protected Money getDiscountAmount(Screening screening);
}

์ƒ์œ„ ํด๋ž˜์Šค์ธ DiscountPolicy ์•ˆ์— ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ๋‘๊ณ , AmountPolicy, PercentDiscountPolicy๊ฐ€ ์ด ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•œ๋‹ค.
์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ DiscountPolicy์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— abstract class(์ถ”์ƒ ํด๋ž˜์Šค)๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค.

DiscountPolicy๋Š” ํ• ์ธ ์—ฌ๋ถ€์™€ ์š”๊ธˆ ๊ณ„์‚ฐ์— ํ•„์š”ํ•œ ์ „์ฒด์ ์ธ ํ๋ฆ„์„ ์ •์˜ํ•˜์ง€๋งŒ, ์‹ค์งˆ์ ์ธ ์š”๊ธˆ์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ถ€๋ถ„์„ ์ถ”์ƒ๋ฉ”์„œ๋“œ์ธ getDiscountAmount() ๋ฉ”์„œ๋“œ์— ์œ„์ž„ํ•œ๋‹ค.

์ด์ฒ˜๋Ÿผ ๊ธฐ๋ณธ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ๋ฆ„์„ ๊ฒฐ์ •ํ•˜๊ณ , ์ค‘๊ฐ„์— ํ•„์š”ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค์—๊ฒŒ ์œ„์ž„ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์„ TEMPLATE METHOD ํŒจํ„ด ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์ด ํŒจํ„ด์„ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.

โญ๏ธ ์ƒ์†๊ณผ ๋‹คํ˜•์„ฑ

Movie

public class Movie {
    private String title;
    private Duration runningTime;
    private Money fee;
    private DiscountPolicy discountPolicy;

    public Movie(String title, Duration runningTime, Money fee, DiscountPolicy discountPolicy) {
        this.title = title;
        this.runningTime = runningTime;
        this.fee = fee;
        this.discountPolicy = discountPolicy;
    }

    public Money getFee() {
        return fee;
    }

    public Money calculateMovieFee(Screening screening) {
        return fee.minus(discountPolicy.calculateDiscountAmount(screening));
    }
}

Movieํด๋ž˜์Šค ์–ด๋””์—๋„ ํ• ์ธ ์ •์ฑ…์ด ์ •์•ก์ œ์ธ์ง€ ์ •๋ฅ ์ œ์ธ์ง€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค.
๊ทธ๋Ÿฐ๋ฐ, ์–ด๋–ป๊ฒŒ ์š”๊ธˆ ๊ณ„์‚ฐ์‹œ ํ• ์ธ ์ •์ฑ…์„ ์ •ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

์ด๋ฅผ ์•Œ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒ์†๊ณผ ๋‹คํ˜•์„ฑ์„ ์•Œ์•„์•ผํ•œ๋‹ค.

๐Ÿ“Œ ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ์˜์กด์„ฑ๊ณผ ์‹คํ–‰ ์‹œ๊ฐ„ ์˜์กด์„ฑ


์œ„์˜ ๊ทธ๋ฆผ์€ Movie์™€ DiscountPolicy ๊ณ„์ธต ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์ด๋‹ค.

Movie๋Š” DiscountPolicy์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฉฐ, AmountDiscountPolicy์™€ PercentDiscountPolicy๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์ธ DiscountPolicy๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.

์—ฌ๊ธฐ์„œ ์ž์„ธํžˆ ๋ด์•ผ ํ•  ๋ถ€๋ถ„์€ Movie ํด๋ž˜์Šค๊ฐ€ AmountDiscountPolicy, PercentDiscountPolicy์™€ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ถ”์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.


๊ทธ๋ ‡๋‹ค๋ฉด Movie์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ์ ์—๋Š” ์กด์žฌ์กฐ์ฐจ ๋ชจ๋ฅด๋˜ AmountDiscountPolicy, PercentDiscountPolicy์˜ ์ธ์Šคํ„ด์Šค์™€ ์‹คํ–‰ ์‹œ์ ์— ํ˜‘๋ ฅ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

Movie์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž

Movie avartar = new Movie("์•„๋ฐ”ํƒ€",
	Duration.ofMinutes(120),
    Money.wons(10000),
    new PercentDisCountPolicy(0,1,....));

์ฝ”๋“œ์ƒ์—์„œ Movie๋Š” DiscountPolicy ์ธ์Šคํ„ด์Šค๋ฅผ ์˜์กดํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ƒ์„ฑ์‹œ์ ์— PercentDiscountPolicy ์ธ์Šคํ„ด์Šค๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.


์ฝ”๋“œ ์ƒ์—์„œ Movie๋Š” DiscountPolicy์— ์˜์กดํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹คํ–‰ ์‹œ์ ์—๋Š” Movie์˜ ์ธ์Šคํ„ด์Šค๋Š” DiscountPolicy๋ฅผ ์ƒ์†ํ•œ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์— ์˜์กดํ•œ๋‹ค.

ํ•ต์‹ฌ์€ ์ฝ”๋“œ์˜ ์˜์กด์„ฑ๊ณผ ์‹คํ–‰ ์‹œ์ ์˜ ์˜์กด์„ฑ์ด ์„œ๋กœ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

๊ฐ„๊ณผํ•˜์ง€๋ง์ž
์œ ์—ฐํ•œ๊ฒŒ ์•„๋ฌด๋ฆฌ ์ข‹๋‹ค์ง€๋งŒ, ์‹คํ–‰, ์ปดํŒŒ์ผ ์‹œ์ ์˜ ์˜์กด์„ฑ์ด ๋‹ค๋ฅผ ์ˆ˜๋ก ์ฝ”๋“œ๋Š” ์œ ์—ฐํ•ด์ง„๋‹ค.
ํ•˜์ง€๋งŒ, ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค. ํ˜„์žฌ Movie ์ธ์Šคํ„ด์Šค๊ฐ€ ์–ด๋–ค ์˜์กด์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ์‹คํ–‰์‹œ์ ๋งˆ๋‹ค ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๊ธฐ๋•Œ๋ฌธ์—
๋””๋ฒ„๊น…ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ๋ฌด์กฐ๊ฑด ์œ ์—ฐํ•œ ์„ค๊ณ„๋„, ์ฝ๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋„ ์ •๋‹ต์ด ์•„๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ƒ์†๊ณผ ์ธํ„ฐํŽ˜์ด์Šค

์ƒ์†์ด ๊ฐ€์น˜ ์žˆ๋Š” ์ด์œ ๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ฌผ๋ ค๋ฐ›์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
(๋‹จ์ˆœํžˆ ๋ฉ”์„œ๋“œ๋‚˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ)

์ƒ์†์€ ๊ทธ์ € ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๊ฒƒ์„ ๋ฌผ๋ ค๋ฐ›๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
์ƒ์†์˜ ํ•ต์‹ฌ์€ ํ™•์žฅ(extends)์— ์žˆ๋‹ค.

Movie์˜ calculateMovieFee ๋ฉ”์„œ๋“œ์™€ ๊ฐ™์ด discountPolicy.calculateDiscountamount ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ๋•Œ, DiscountPolicy๋ฅผ ์ƒ์†๋ฐ›์€ ์ธ์Šคํ„ด์Šค๋“ค์ด ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋“ค์ด ๋“ค์–ด์™€๋„ ๋ฉ”์‹œ์ง€๋ฅผ ์†ก์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ฝ”๋“œ์ƒ์—์„œ ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ๋‚˜์˜ค๋Š” ๋ชจ๋“  ์žฅ์†Œ์—์„œ ์ž์‹ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค.

์ด์ฒ˜๋Ÿผ ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ถ€๋ชจํด๋ž˜์Šค๋ฅผ ๋Œ€์‹  ํ•˜๋Š” ๊ฒƒ์„ ์—…์บ์ŠคํŒ…์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

Movie ์ž…์žฅ์—์„œ๋Š” ์ž์‹ ๊ณผ ํ˜‘๋ ฅํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ธ์ง€๊ฐ€ ์ค‘์š”ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, calculateDiscountAmount๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ์ค‘์š”ํ•˜๋‹ค.

๐Ÿ“Œ ๋‹คํ˜•์„ฑ

๋ฉ”์‹œ์ง€์™€ ๋ฉ”์„œ๋“œ์˜ ์ฐจ์ด๋ฅผ ์•Œ์ž.

Movie๋Š” DiscountPolicy์˜ ์ธ์Šคํ„ด์Šค์—๊ฒŒ calculateDiscountAmount ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•œ๋‹ค.
์ดํ›„ ์—ฐ๊ฒฐ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
Movie๊ฐ€ ๋™์ผํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜์ง€๋งŒ, ์‹ค์ œ๋กœ ์–ด๋–ค ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋  ๊ฒƒ์ธ์ง€๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ๊ฐ์ฒด ํด๋ž˜์Šค๊ฐ€ ๋ฌด์—‡์ด๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š”๋ฐ, ์ด๋ฅผ ๋‹คํ˜•์„ฑ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ฉ”์‹œ์ง€์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ ์‹œ์ ์— ๋ฐ”์ธ๋”ฉ ํ•˜๋Š” ๊ฒƒ์„ ์ง€์—ฐ ๋ฐ”์ธ๋”ฉ(lazy binding), ๋™์  ๋ฐ”์ธ๋”ฉ(dynamic binding)์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๊ทธ์— ๋ฐ˜ํ•ด ์ „ํ†ต์ ์ธ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ฒ˜๋Ÿผ ์ปดํŒŒ์ผ ์‹œ์ ์— ์‹คํ–‰๋  ํ•จ์ˆ˜๋‚˜ ํ”„๋กœ์‹œ์ ธ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์„ ์ดˆ๊ธฐ ๋ฐ”์ธ๋”ฉ, ์ ์ •๋ฐ”์ธ๋”ฉ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

ํ•˜๋‚˜์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์— ์—ฐ๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์ง€์—ฐ๋ฐ”์ธ๋”ฉ์ด๋ผ๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

โญ๏ธ ์ถ”์ƒํ™”์™€ ์œ ์—ฐ์„ฑ

๐Ÿ“Œ ์ถ”์ƒํ™”์˜ ํž˜


์œ„ ๊ทธ๋ฆผ์€ ์ถ”์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ 2๊ฐ€์ง€ ์žฅ์ ์„ ๋ณด์—ฌ์ค€๋‹ค.

  1. ์ถ”์ƒํ™”์˜ ๊ณ„์ธต๋งŒ ๋”ฐ๋กœ ๋–ผ์–ด๋†“๊ณ  ๋ณด๋ฉด ์š”๊ตฌ ์‚ฌํ•ญ์˜ ์ •์ฑ…์„ ๋†’์€ ์ˆ˜์ค€์—์„œ ์„œ์ˆ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ex) ์˜ํ™” ์˜ˆ๋งค ์š”๊ธˆ์€ ์ตœ๋Œ€ ํ•˜๋‚˜์˜ ํ• ์ธ ์ •์ฑ…๊ณผ ๋‹ค์ˆ˜์˜ ํ• ์ธ ์กฐ๊ฑด์„ ์ด์šฉํ•ด ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  1. ์ถ”์ƒํ™”๋ฅผ ์ด์šฉํ•˜๋ฉด ์„ค๊ณ„๊ฐธ ์œ ์—ฐํ•ด์ง„๋‹ค.

์œ„ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ํ•˜๋‚˜์˜ ๋ฌธ์žฅ์œผ๋กœ ์ •๋ฆฌํ•˜๋ฉด
"์˜ํ™” ์˜ˆ๋งค ์š”๊ธˆ์€ ์ตœ๋Œ€ ํ•˜๋‚˜์˜ ํ• ์ธ ์ •์ฑ…๊ณผ ๋‹ค์ˆ˜์˜ ํ• ์ธ ์กฐ๊ฑด์„ ์ด์šฉํ•ด ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค."์™€ ๊ฐ™๋‹ค.
์œ„ ๋ฌธ์žฅ์€ "๊ธˆ์•ก ํ• ์ธ ์ •์ฑ…๊ณผ ๋‘ ๊ฐœ์˜ ์ˆœ์„œ ์กฐ๊ฑด, ํ•œ ๊ฐœ์˜ ๊ธฐ๊ฐ„ ์กฐ๊ฑด์„ ์ด์šฉํ•ด ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค"๋ผ๋Š” ๋ฌธ์žฅ์„ ํฌ๊ด„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ์ค‘์š”ํ•˜๋‹ค.

์ถ”์ƒํ™”๋ฅผ ํ†ตํ•ด ์ƒ์œ„ ์ •์ฑ…์„ ๊ธฐ์ˆ ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๊ธฐ๋ณธ์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ˜‘๋ ฅ ํ๋ฆ„์„ ๊ธฐ์ˆ ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
์˜ํ™” ์˜ˆ๋งค ๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•œ ํ๋ฆ„์€ ํ•ญ์ƒ Movie -> DiscountPolicy -> DiscountCondition ์ˆœ์„œ๋กœ ํ˜๋Ÿฌ๊ฐ„๋‹ค.
ํ• ์ธ ์ •์ฑ…, ์กฐ๊ฑด์˜ ์ž์‹๋“ค์€ ์ถ”์ƒํ™”๋ฅผ ์ด์šฉํ•ด์„œ ์ •์˜ํ•œ ํ๋ฆ„์— ๊ทธ๋Œ€๋กœ ๋”ฐ๋ฅด๊ฒŒ ๋œ๋‹ค.

์ถ”์ƒํ™”๊ฐ€ ์œ ์—ฐํ•œ ์„ค๊ณ„๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ์ด์œ ๋Š” ์„ค๊ณ„๊ฐ€ ๊ตฌ์ฒด์ ์ธ ์ƒํ™ฉ์— ๊ฒฐํ•ฉ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Movie๋Š” ํŠน์ •ํ•œ ํ• ์ธ ์ •์ฑ…์— ๋ฌถ์ด์ง€ ์•Š๋Š”๋‹ค. ํ• ์ธ ์ •์ฑ…์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๊ฐ€ DiscountPolicy๋ฅผ ์ƒ์†๋ฐ›๊ณ  ์žˆ๋‹ค๋ฉด ์–ด๋–ค ํด๋ž˜์Šค์™€๋„ ํ˜‘๋ ฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

DiscountPolicy ์—ญ์‹œ ํŠน์ • ํ• ์ธ ์กฐ๊ฑด์— ๋ฌถ์—ฌ์žˆ์ง€ ์•Š๋‹ค. DiscountCondition์„ ์ƒ์†๋ฐ›์€ ์–ด๋–ค ํด๋ž˜์Šค์™€๋„ ํ˜‘๋ ฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ด ๋ชจ๋“  ๊ฒƒ์ด ์ถ”์ƒํ™” ๋•๋ถ„์ด๋‹ค.

๐Ÿ“Œ ์œ ์—ฐํ•œ ์„ค๊ณ„

ํ• ์ธ ์ •์ฑ…์ด ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” ๋ชจ๋‘ ์‚ดํŽด๋ดค๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ํ• ์ธ ์ •์ฑ…์ด ์—†๋Š” ๊ฒฝ์šฐ๋Š” ์–ด๋–ป๊ฒŒ ํ• ๊นŒ?

์ด๋Ÿฐ ๊ฒฝ์šฐ์—, NoneDiscountPolicy๋ผ๋Š” ๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜์—ฌ, ํ• ์ธ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ , ์ด ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜์ž.

public class NoneDiscountPolicy extends DiscountPolicy {
    @Override
    protected Money getDiscountAmount(Screening screening) {
        return Money.ZERO;
    }
}

์ด ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜๋ฉด Movie ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š”๋„ ์—†๊ณ , ๊ธฐ๋Šฅ์ƒ ๋ฌธ์ œ ์—†์ด ์ž‘๋™ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ

์ƒ์†์€ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•ด์„œ ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋‹ค. ๊ฐœ์ฒด์ง€ํ–ฅ ์„ค๊ณ„์™€ ๊ด€๋ จ๋œ ์ž๋ฃŒ๋ฅผ ๋ณธ ์‚ฌ๋žŒ๋“ค์€ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด์„œ๋Š” ์ƒ์†๋ณด๋‹ค๋Š” ํ•ฉ์„ฑ(composition)์ด ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋ผ๋Š” ์ด์•ผ๊ธฐ๋ฅผ ๋งŽ์ด ๋“ค์—ˆ์„ ๊ฒƒ์ด๋‹ค.
ํ•ฉ์„ฑ์€ ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ž์‹ ์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ํฌํ•จํ•ด์„œ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋งํ•œ๋‹ค.

๋‹ค์Œ์€ ํ•ฉ์„ฑ ๋ฐฉ์‹์„ ์ƒ์†์œผ๋กœ ๋ณ€๊ฒฝํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ์ด๋‹ค.

์˜ˆ์‹œ๋กœ ๋“ค์ž๋ฉด Movie๊ฐ€ DiscountPolicy ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์ด ๋ฐ”๋กœ ํ•ฉ์„ฑ์ด๋‹ค.

๋งŒ์•ฝ์— ์ด๊ฒƒ์„ ์ƒ์†์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ ์žํ•˜๋ฉด Movie๋ฅผ ์ƒ์†๋ฐ›๋Š” AmountdiscountMovie, PercentDiscountMoive๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์ƒ์† ๋Œ€์‹  ํ•ฉ์„ฑ์„ ์„ ํ˜ธํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

โœ”๏ธŽ ์ƒ์†

์ƒ์†์€ ๋‘ ๊ฐ€์ง€ ๊ด€์ ์—์„œ ์„ค๊ณ„์— ์•ˆ ์ข‹์€ ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค.

  • ํ•˜๋‚˜๋Š” ์ƒ์†์ด ์บก์Аํ™”๋ฅผ ์œ„๋ฐ˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
    - ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์ด ์ž์‹ ํด๋ž˜์Šค์—๊ฒŒ ๋…ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์บก์Аํ™”๊ฐ€ ์•ฝํ™”๋œ๋‹ค.
  • ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์„ค๊ณ„๋ฅผ ์œ ์—ฐํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
    - ์ƒ์†์€ ๋ถ€๋ชจ ํด๋ž˜์Šค์™€ ์ž์‹ ํด๋ž˜์Šค ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ์ปดํŒŒ์ผ ์‹œ์ ์— ๊ฒฐ์ •ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์‹คํ–‰ ์‹œ์ ์— ๊ฐ์ฒด์˜ ์ข…๋ฅ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

โœ”๏ธŽ ํ•ฉ์„ฑ

Movie๋Š” ์š”๊ธˆ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด DiscountPolicy์˜ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.
Movie๊ฐ€ DiscountPolicy์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์•ฝํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜๋Š”์ ์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
Movie๋Š” DiscountPolicy์˜ calculateDiscountAmount ๋ฉ”์‹œ์ง€๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

์ด๊ฒƒ์„ ํ•ฉ์„ฑ์ด๋ผ๊ณ  ํ•œ๋‹ค.

ํ•ฉ์„ฑ์€ ์ƒ์†์ด ๊ฐ€์ง€๋Š” ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ์ ์„ ๋ชจ๋‘ ํ•ด๊ฒฐํ•œ๋‹ค.
ํ•ฉ์„ฑ์€ ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜๋œ ๋ฉ”์‹œ์ง€๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์บก์Аํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์˜์กดํ•˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์‰ฝ๊ฒŒ ๊ต์ฒด ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ค๊ณ„๊ฐ€ ์œ ์—ฐํ•ด์ง„๋‹ค.

์ƒ์†์„ ๋ฌด์กฐ๊ฑด ์‚ฌ์šฉํ•˜์ง€ ๋ง๋ผ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์„ค๊ณ„์—์„œ๋Š” ์ƒ์†๊ณผ ํ•ฉ์„ฑ์„ ์ ์ ˆํžˆ ์„ž์–ด ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
Movie์™€ DiscountPolicy๋Š” ํ•ฉ์„ฑ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด์žˆ์ง€๋งŒ DiscountPolicy, AmountDiscountPolicy, PercentDiscountPolicy๋Š” ์ƒ์†๊ด€๊ณ„๋กœ ๋˜์–ด์žˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ์ค‘๋ณต ๊ตฌํ˜„๋œ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ƒ์†๋„ ์ ์ ˆํžˆ ์„ž์–ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

โญ๏ธ ๋А๋‚€์ 

๋งŽ์€ ์ฑ…๋“ค๊ณผ ๊ธ€์—์„œ ์ƒ์†์€ ๋˜๋„๋ก ํ”ผํ•˜๋ผ๊ณ  ๋งํ•œ๋‹ค. ์ด๋•Œ๋ฌธ์— ์ƒ์†์€ ์ตœ๋Œ€ํ•œ ๊ธฐํ”ผํ•˜๊ณ  ๊ตฌํ˜„, ํ•ฉ์„ฑ์„ ํ™œ์šฉํ•ด์•ผํ•œ๋‹ค๋Š” ์ƒ๊ฐ์— ์‚ฌ๋กœ์žกํ˜€์žˆ์—ˆ๋Š”๋ฐ ์ด๋ฒˆ ๊ธฐํšŒ์— ์ƒ๊ฐ์„ ์ •์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

๋น„์Šทํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋˜ ๋ฉ”์„œ๋“œ์™€ ๋ฉ”์‹œ์ง€์˜ ์ฐจ์ด ๋˜ํ•œ ๋„“๊ฒŒ ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
๋ฉ”์„œ๋“œ๋Š” ์ฝ”๋“œ์˜ ์ž์œจ์„ฑ์„ ๋†’์—ฌ์ฃผ๊ณ  ๋ฉ”์‹œ์ง€๋Š” ๊ฐ์ฒด๋“ค๊ฐ„์˜ ํ˜‘๋ ฅ์„ ์œ„ํ•œ ์ˆ˜๋‹จ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

์ฃผ๋กœ DB์— ์˜์กดํ•˜๊ณ , DB ์ค‘์‹ฌ์ ์œผ๋กœ ์ƒ๊ฐํ–ˆ๋˜๊ฑฐ ๊ฐ™์€๋ฐ ์ ์  ์ด๋Ÿฐ ์ƒ๊ฐ์—์„œ ํƒˆํ”ผํ•˜๊ณ  ์žˆ๋‹ค.
๊ฐ€์žฅ ํฌ๊ฒŒ ๋†€๋ž€์ ์€ ์œ ์—ฐํ•จ์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•œ ๋ถ€๋ถ„์ด๋‹ค. ์ถ”์ƒํ™” ๋ถ€๋ถ„์—์„œ ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“ค์ˆ˜๋ก ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์ง„๋‹ค๊ณ  ๋งํ–ˆ๋Š”๋ฐ ์ด ๋ถ€๋ถ„์€ ํ•œ ๋ฒˆ๋„ ์ƒ๊ฐํ•ด๋ณด์ง€ ๋ชปํ•œ ๋ถ€๋ถ„์ด์—ˆ๋‹ค. ๋งŽ์€ ์ƒ๊ฐ์„ ํ•˜๊ฒŒ ๋œ ์ฑ•ํ„ฐ์˜€๋‹ค.


์ถœ์ฒ˜
์˜ค๋ธŒ์ ํŠธ - ์ฝ”๋“œ๋กœ ์ดํ•ดํ•˜๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„
https://github.com/eternity-oop/object

0๊ฐœ์˜ ๋Œ“๊ธ€