์บก์ํ (Encapsulation)
๋ชฐ๋ผ๋ ๋๋ ๊ฐ์ฒด ๋ด๋ถ์ ์ธ๋ถ์ ์ธ ์ฌํญ์ ๊ฐ์ถ๋ ๊ฒ
๐ ๋ชฉ์ : ๋ณ๊ฒฝํ๊ธฐ ์ฌ์ด ๊ฐ์ฒด ๋ง๋ค๊ธฐ
์บก์ํ๋ฅผ ํตํด ๊ฐ์ฒด ๋ด๋ถ๋ก์ ์ ๊ทผ์ ์ ํํ๋ฉด ๊ฐ์ฒด์ ๊ฐ์ฒด ์ฌ์ด์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์์ โ ์ค๊ณ ์ข๋ ์ฝ๊ฒ ๋ณ๊ฒฝ ๊ฐ๋ฅ
โก๏ธ ๊ฐ์ฒด๋ฅผ ์ธํฐํ์ด์ค์ ๊ตฌํ์ผ๋ก ๋๋๊ณ ์ธํฐํ์ด์ค๋ง์ ๊ณต๊ฐํด ๊ฐ์ฒด ์ฌ์ด์ ๊ฒฐํฉ๋ ๋ฎ์ถ๊ณ ๋ณ๊ฒฝํ๊ธฐ ์ฌ์ด ์ฝ๋ ์์ฑ
์์ง๋ (Cohesion)
๋ฐ์ ํ๊ฒ ์ฐ๊ด๋ ์์ ๋ง์ ์ํํ๊ณ ์ฐ๊ด์ฑ ์๋ ์์ ์ ๋ค๋ฅธ ๊ฐ์ฒด์๊ฒ ์์ ๐ ์์ง๋๊ฐ ๋์
์์ ์ ๋ฐ์ดํฐ๋ฅผ ์ค์ค๋ก ์ฒ๋ฆฌํ๋ ์์จ์ ์ธ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋ฉด ๊ฒฐํฉ๋↓, ์์ง๋↑
โจ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ (Object-Oriented Programming)
๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ํ๋ก์ธ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ ๐ ๋ฐ์ดํฐ์ ํ๋ก์ธ์ค๊ฐ ๋์ผํ ๋ชจ๋(๊ฐ์ฒด) ๋ด๋ถ์ ์์น
- ์์กด์ฑ์ ํต์ ํ๊ณ ํ๋์ ๋ณ๊ฒฝ์ผ๋ก ์ธํ ์ฌํ๊ฐ ์ฌ๋ฌ ํด๋์ค๋ก ์ ํ๋๋ ๊ฒ์ ํจ์จ์ ์ผ๋ก ์ต์
- ํ๋์ ๊ธฐ๋ฅ์ ์์ฑํ๋ ๋ฐ ํ์ํ ์ฑ ์์ด ์ฌ๋ฌ ๊ฐ์ฒด์ ๊ฑธ์ณ ๋ถ์ฐ = ์ฑ ์์ ์ด๋
๐ ํ๋ ฅํ๋ ๊ฐ์ฒด ์ฌ์ด์ ์์กด์ฑ์ ์ ์ ํ๊ฒ ๊ด๋ฆฌํ๋ ์ค๊ณ = ์ข์ ๊ฐ์ฒด์งํฅ ์ค๊ณ
๐ฝ๏ธ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์์ - ์ํ ์๋งค ์์คํ
์๊ตฌ์ฌํญ์ ์ฑ ์ฐธ๊ณ
๐ ์ํ, ์์, ํ ์ธ์กฐ๊ฑด, ํ ์ธ์ ์ฑ ์ผ๋ก ๋๋ฉ์ธ ๊ตฌ์ฑ
- ์ด๋ค ํด๋์ค๊ฐ ํ์ํ์ง ๊ณ ๋ฏผํ๊ธฐ ์ ์ ์ด๋ค ๊ฐ์ฒด๋ค์ด ํ์ํ์ง ๋จผ์ ๊ณ ๋ฏผ !
- ๊ฐ์ฒด๋ฅผ ๋ ๋ฆฝ์ ์ธ ์กด์ฌ๊ฐ ์๋ ํ๋ ฅํ๋ ๊ณต๋์ฒด์ ์ผ์์ผ๋ก ์๊ฐ
- ๊ฐ์ฒด ๋ด๋ถ์ ๋ํ ์ ๊ทผ์ ํต์ ํจ์ผ๋ก์จ ๊ฐ์ฒด๋ฅผ ์์จ์ ์ธ ์กด์ฌ๋ก ๋ง๋ฆ ๐ ์ธ๋ถ ๊ฐ์ญ ์ต์ํ
์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฒด์ ์ํ๋ ์จ๊ธฐ๊ณ ํ๋๋ง ์ธ๋ถ์ ๊ณต๊ฐ
โด๏ธ ํ ์ธ ์ ์ฑ
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์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ถ์ํด๋์ค๋ก ๊ตฌํ
- ํ๋์ ํ ์ธ ์ ์ฑ ์ ์ฌ๋ฌ ๊ฐ์ ํ ์ธ ์กฐ๊ฑด์ ํฌํจ ๊ฐ๋ฅ โ ๋ฆฌ์คํธ๋ฅผ ์ฌ์ฉํด ์ฌ๋ฌ ๊ฐ์ DiscountCondition ์ธ์คํด์ค ํ์ฉ
- ๋ง์กฑํ๋ ํ ์ธ ์กฐ๊ฑด์ด ํ๋๋ผ๋ ์กด์ฌํ๋ฉด ์ถ์ ๋ฉ์๋์ธ getDiscountAmount ํธ์ถํด์ ํ ์ธ ์๊ธ ๊ณ์ฐ
์กด์ฌํ์ง ์๋ค๋ฉด, Screening์ getMovieFee ๋ฉ์๋ ํธ์ถํด์ ์๋ ์ํ ๊ฐ๊ฒฉ ๋ฐํ - ์ค์ ๋ก ์๊ธ์ ๊ณ์ฐํ๋ ๋ถ๋ถ์ ์ถ์ ๋ฉ์๋์ธ getDiscountAmount์๊ฒ ์์ ๐ Template Method
โจ Template Method
๐ ๋ถ๋ชจ ํด๋์ค์ ๊ธฐ๋ณธ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ํ๋ฆ์ ๊ตฌํํ๊ณ ์ค๊ฐ์ ํ์ํ ์ฒ๋ฆฌ๋ฅผ ์์ ํด๋์ค์๊ฒ ์์ํ๋ ๋์์ธ ํจํด
- ๊ธ์ก ํ ์ธ ์ ์ฑ
public class AmountDiscountPolicy extends DiscountPolicy {
private Money discountAmount;
public AmountDiscountPolicy(Money discountAmount, DiscountCondtion ... conditions){
super(conditions);
this.discountAmount = discountAmount;
}
@Override
protected Money getDiscountAmount(Screening screening) {
return discountAmount;
}
}
- ๋น์จ ํ ์ธ ์ ์ฑ
public class PercentDiscountPolicy extends DiscountPolicy {
private double percent;
public PercentDiscountPolicy(double percent, DiscountCondtion ... conditions){
super(conditions);
this.percent = percent;
}
@Override
protected Money getDiscountAmount(Screening screening) {
return screening.getMovieFee().times(percent);
}
}
- 0์ ํ ์ธ ์ ์ฑ (ํ ์ธ ์ ์ฑ X)
public class NoneDiscountPolicy extends DiscountPolicy {
@Override
protected Money getDiscountAmount(Screening screening){
return Money.ZERO;
}
}
๐ ๋ถ๋ชจ ํด๋์ค์ธ DiscountPolicy์์ ํ ์ธ ์กฐ๊ฑด์ด ์์ ๊ฒฝ์ฐ getDiscountAmount() ๋ฉ์๋๋ฅผ ํธ์ถํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ค ๊ฐ์ ๋ฐํํ๋๋ผ๋ ์๊ด ์์...
๐ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด DiscountPolicy ํด๋์ค๋ฅผ ์ธํฐํ์ด์ค๋ก ๋ณ๊ฒฝํ๊ณ , ๊ธฐ์กด์ ์๋ DiscountPolicy ํด๋์ค์ ์ด๋ฆ์ DefaultDiscountPolicy๋ก ๋ณ๊ฒฝํ ํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋๋ก ์์ ํด์ผ ํจ.
โด๏ธ ํ ์ธ ์กฐ๊ฑด
public interface DiscountCondition {
boolean isSatisfiedBy(Screening screening);
}
- ์๋ฒ ์กฐ๊ฑด
public class SequenceCondition implements DiscountCondition {
private int sequence;
public SequenceCondition(int sequence){
this.sequence = sequence;
}
public boolean isSatisfiedBy(Screening screening){
return screening.isSequence(sequence);
}
}
- ๊ธฐ๊ฐ ์กฐ๊ฑด
public class PeriodCondition implements DiscountCondition {
private DayOfWeek dayOfWeek;
private LocalTime startTime;
private LocalTime endTime;
public PeriodCondition(DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime){
this.dayOfWeek = dayOfWeek;
this.startTime = startTime;
this.endTime = endTime;
}
public boolean isSatisfiedBy(Screening screening){
return screening.getStartTime().getDayOfWeek().equals(dayOfWeek) &&
startTime.compareTo(screening.getStartTime().toLocalTime()) <= 0 &&
endTime.compareTo(screening.getStartTime().toLocalTime()) >= 0;
}
}
โด๏ธ ์ํ
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 toystory = new Movie("ํ ์ด์คํ ๋ฆฌ",
Duration.ofMinutes(100),
Money.wons(10000),
new AmountDiscountPolicy(Money.wons(800),
new SequenceCondition(1),
new SequenceCondition(10),
new PeriodCondition(DayOfWeek.MONDAY, LocalTime.of(10, 0), LocalTime(11, 59)),
new PeriodCondition(DayOfWeek.SUNDAY, LocalTime.of(10, 0), LocalTime(20, 59))));
Movie titanic = new Movie("ํ์ดํ๋",
Duration.ofMinutes(180),
Money.wons(10000),
new PercentDiscountPolicy(0.1,
new PeriodCondition(DayOfWeek.MONDAY, LocalTime.of(10, 0), LocalTime(15, 59)),
new SequenceCondition(2),
new PeriodCondition(DayOfWeek.SUNDAY, LocalTime.of(10, 0), LocalTime(19, 59))));
โจ Movie ํด๋์ค์์ ํ ์ธ ์ ์ฑ ์ ๊ฒฐ์ ํ๋ ์กฐ๊ฑด๋ฌธ X ๐ ์์ & ๋คํ์ฑ
์์กด์ฑ - ์์๊ณผ ๋คํ์ฑ, ์ธํฐํ์ด์ค
- Movie๋ DiscountPolicy์ ์ฐ๊ฒฐ
- AmountDiscountPolicy์ PercentDiscountPolicy๋ ์ถ์ ํด๋์ค์ธ DiscountPolicy๋ฅผ ์์ ๋ฐ์
๐ ๋ค๋ฅธ ํด๋์ค์ ์ ๊ทผํ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ง๊ฑฐ๋ ํด๋น ํด๋์ค์ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ ๋ ํด๋์ค ์ฌ์ด์ "์์กด์ฑ์ด ์กด์ฌํ๋ค"๊ณ ํจ
- Movie์ ์ธ์คํด์ค๋ ์คํ ์์ AmountDiscountPolicy์ PercentDiscountPolicy์ ์ธ์คํด์ค์ ์์กดํ์ง๋ง ์ฝ๋ ์์ผ๋ก๋ DiscountPolicy์๋ง ์์กดํ๊ณ ์์ !
๐ ์ฝ๋์ ์์กด์ฑ๊ณผ ์คํ ์์ ์ ์์กด์ฑ์ด ๋ค๋ฆ = ํด๋์ค ์ฌ์ด์ ์์กด์ฑ๊ณผ ๊ฐ์ฒด ์ฌ์ด์ ์์กด์ฑ์ด ๋ค๋ฆ
๐ ์ ์ฐ, ์ฝ๊ฒ ์ฌ์ฌ์ฉ, ํ์ฅ ๊ฐ๋ฅํ ๊ฐ์ฒด์งํฅ ์ค๊ณ์ ํน์ง
ํ์ง๋ง, ์ค๊ณ๊ฐ ์ ์ฐํด์ง์๋ก ์ฝ๋๋ฅผ ์ดํดํ๊ณ ๋๋ฒ๊น ํ๊ธฐ๋ ์ด๋ ค์์ง๋ค.
๊ทธ๋ฌ๋ฏ๋ก ํญ์ ์ ์ฐ์ฑ๊ณผ ๊ฐ๋ ์ฑ ์ฌ์ด๋ฅผ ๊ณ ๋ฏผํด์ผ ํจ.
โณ๏ธ ์์
์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ธฐ์กด ํด๋์ค๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์์ฑ๊ณผ ํ๋์ ์๋ก์ด ํด๋์ค์ ํฌํจ์ํฌ ์ ์์.
๋ถ๋ชจ ํด๋์ค์ ๊ตฌํ์ ๊ณต์ ํ๋ฉด์๋ ํ๋์ด ๋ค๋ฅธ ์์ ํด๋์ค๋ฅผ ์ฝ๊ฒ ์ถ๊ฐ ๊ฐ๋ฅ
- ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์ ํ๋ ๊ฒ = ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ํ์ ์ผ๋ก ๋ณํ๋๋ ๊ฒ = ์ ์บ์คํ (Upcasting)
- ๊ตฌํ ์์
- ์ฝ๋ ์ฌ์ฌ์ฉ ๋ชฉ์
- ์ธํฐํ์ด์ค ์์
- ๋คํ์ ์ธ ํ๋ ฅ์ ์ํด ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๊ณต์ ํ ์ ์๋๋ก ์์ ์ด์ฉ
- ๋คํ์ ์ธ ํ๋ ฅ์ ์ํด ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๊ณต์ ํ ์ ์๋๋ก ์์ ์ด์ฉ
โณ๏ธ ๋คํ์ฑ
๋์ผํ ๋ฉ์์ง๋ฅผ ์์ ํ์ ๋ ๊ฐ์ฒด์ ํ์ ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์๋ต
์ปดํ์ผ ์๊ฐ ์์กด์ฑ๊ณผ ์คํ ์๊ฐ ์์กด์ฑ์ ๋ค๋ฅด๊ฒ ๋ง๋ค ์ ์๋ ๊ฐ์ฒด์งํฅ์ ํน์ฑ์ ์ด์ฉํด ์๋ก ๋ค๋ฅธ ๋ฉ์๋ ์คํ
๐ ์คํ์์ ์ ์คํ๋ ๋ฉ์๋ ๊ฒฐ์ = Lazy Binding(์ง์ฐ ๋ฐ์ธ๋ฉ) = Dynamic Binding(๋์ ๋ฐ์ธ๋ฉ)
ex). AmountDiscountPolicy ๋๋ PercentDiscountPolicy
โจ ์์๋ฐ๋ ๊ฒ = ๋คํ์ฑ ๊ตฌํ
โณ๏ธ ์ธํฐํ์ด์ค
์ถ์ ํด๋์ค๋ฅผ ์ด์ฉํด ๋คํ์ฑ์ ๊ตฌํํ๋ ํ ์ธ ์ ์ฑ ๊ณผ ๋ฌ๋ฆฌ ํ ์ธ ์กฐ๊ฑด์ ๊ตฌํ์ ๊ณต์ ํ ํ์๊ฐ ์์ผ๋ฏ๋ก ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํด ํ์ ๊ณ์ธต ๊ตฌํ
์์์ ๋จ์ ๊ณผ ํฉ์ฑ
- ์บก์ํ ์๋ฐ
- ๋ถ๋ชจ ํด๋์ค์ ๊ตฌํ์ด ์์ ํด๋์ค์๊ฒ ๋ ธ์ถ๋๋ฏ๋ก ์บก์ํ ์ฝํ
- ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋๋๋ก ๋ง๋ค๊ธฐ ๋๋ฌธ์ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ ๋ ์์ ํด๋์ค๋ ํจ๊ป ๋ณ๊ฒฝ๋ ์ ์์
- ์ค๊ณ๊ฐ ์ ์ฐํ์ง X
- ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค ์ฌ์ด์ ๊ด๊ณ๋ฅผ ์ปดํ์ผ ์์ ์ ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์ ์คํ ์์ ์ ๊ฐ์ฒด์ ์ข ๋ฅ ๋ณ๊ฒฝ ๋ถ๊ฐ
โณ๏ธ ํฉ์ฑ
์ธํฐํ์ด์ค์ ์ ์๋ ๋ฉ์์ง๋ฅผ ํตํด์๋ง ์ฝ๋ ์ฌ์ฌ์ฉ
ex). Movie์ DiscountPolicy๋ ํฉ์ฑ ๊ด๊ณ๋ก ์ฐ๊ฒฐ โ ์๊ธ ๊ณ์ฐํ๊ธฐ ์ํด DiscountPolicy ์ฝ๋ ์ฌ์ฌ์ฉ
๐ ์ฝ๋ ์ฌ์ฌ์ฉ์ ์ํด์๋ ์์๋ณด๋ค๋ ํฉ์ฑ ์ ํธ !
ํ์ง๋ง, ๋คํ์ฑ์ ์ํด ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ ์์๊ณผ ํฉ์ฑ์ ํจ๊ป ์กฐํฉํด์ ์ฌ์ฉ !
'Java > ๐ ์ค๋ธ์ ํธ : ์ฝ๋๋ก ์ดํดํ๋ ๊ฐ์ฒด์งํฅ ์ค๊ณ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ค๋ธ์ ํธ : ์ฝ๋๋ก ์ดํดํ๋ ๊ฐ์ฒด์งํฅ ์ค๊ณ] ํ๋ ฅ, ์ฑ ์, ์ญํ (0) | 2024.09.21 |
---|