
์ค๋ณต ์ฝ๋๋ ๋ณ๊ฒฝ์ ๋ฐฉํดํ๋ค.
์ด๊ฒ์ด ์ค๋ณต ์ฝ๋๋ฅผ ์ ๊ฑฐํด์ผ ํ๋ ๊ฐ์ฅ ํฐ ์ด์ ๋ค. ์ค๋ณต ์ฝ๋๊ฐ ๊ฐ์ง๋ ๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ ์ฝ๋๋ฅผ ์์ ํ๋ ๋ฐ ํ์ํ ๋
ธ๋ ฅ์ ๋ช ๋ฐฐ๋ก ์ฆ๊ฐ ์ํจ๋ค๋ ๊ฒ์ด๋ค. ์ค๋ณต ์ฌ๋ถ๋ฅผ ํ๋จํ๋ ๊ธฐ์ค์ ๋ณ๊ฒฝ์ด๋ค. ์๊ตฌ์ฌํญ์ด ๋ณ๊ฒฝ ๋์ ๋ ๋ ์ฝ๋๋ฅผ ํจ๊ป ์์ ํด์ผ ํ๋ค๋ฉด ์ด ์ฝ๋๋ ์ค๋ณต์ด๋ค.
DRY ์์น
DRY๋ '๋ฐ๋ณตํ์ง ๋ง๋ผ'๋ผ๋ ๋ป์ Don't Repeat Yourself์ ์ฒซ ๊ธ์๋ฅผ ๋ชจ์ ๋ง๋ ์ฉ์ด๋ก ๊ฐ๋จํ ๋งํด ๋์ผํ ์ง์์ ์ค๋ณตํ์ง ๋ง๋ผ๋ ๊ฒ์ด๋ค.
DRY ์์น์ ํ๋ฒ, ๋จ ํ๋ฒ(Once and Only One) ์์น ๋๋ ๋จ์ผ ์ง์ ์ ์ด(Single-Point Control) ์์น์ด๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค.
์์์ ์ด์ฉํด ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ถ๋ชจ ํด๋์ค์ ๊ฐ๋ฐ์๊ฐ ์ธ์ ๋ ๊ฐ์ ์ด๋ ์ถ๋ก ๊ณผ์ ์ ์ ํํ๊ฒ ์ดํดํด์ผ ํ๋ค. ์ด๊ฒ์ ์์ ํด๋์ค์ ์์ฑ์๊ฐ ๋ถ๋ชจ ํด๋์ค์ ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ํ ์ ํํ ์ง์์ ๊ฐ์ ธ์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
๋ฐ๋ผ์ ์์์ ๊ฒฐํฉ๋๋ฅผ ๋์ธ๋ค๊ณ ์ด์ผ๊ธฐํ ์ ์๋ค.
๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค ์ฌ์ด์ ๊ฒฐํฉ์ด ๋ฌธ์ ์ธ ์ด์ ๋ฅผ ์ดํด๋ณด์.
NightlyDiscountPhone์ ๋ถ๋ชจ ํด๋์ค์ธ Phone์ calculateFee ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ๋ค. ๋ํ ๋ฉ์๋ ์์์ super ์ฐธ์กฐ๋ฅผ ์ด์ฉํด ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. NightlyDiscountPhone์ calculateFee ๋ฉ์๋๋ ์์ ์ด ์ค๋ฒ๋ผ์ด๋ฉํ Phone์ calculateFee ๋ฉ์๋๊ฐ ๋ชจ๋ ํตํ์ ๋ํ ์๊ธ์ ์ดํฉ์ ๋ฐํํ๋ค๋ ์ฌ์ค์ ๊ธฐ๋ฐํ๊ณ ์๋ค.
ํ์ง๋ง ์ธ๊ธ์ ๋ถ๊ณผํ๋ ์๊ตฌ์ฌํญ์ด ์ถ๊ฐ๋๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น? calculateFee ๋ฉ์๋์์ ๊ฐ์ ๋ฐํํ ๋ taxRate๋ฅผ ์ด์ฉํด ์ธ๊ธ์ ๋ถ๊ณผํด์ผ ํ๋ค.
public class Phone {
private double taxRate; // ์ธ๊ธ ๋ถ๊ณผ ์๊ตฌ์ฌํญ์ผ๋ก ์ธํ ๋ณ์ ์ถ๊ฐ
public Phone(Money amount, Duration seconds, double taxRate) {
...
this.taxTate = taxRate;
}
public calculateFee() {
...
return result.plus(result.times(taxRate));
}
public double getTaxRate() {
return this.taxRate;
}
}
NigthlyDiscountPhone์ ์์ฑ์์์ ์ ๋ฌ๋ฐ์ taxRate๋ฅผ ๋ถ๋ชจ ํด๋์ค์ธ Phone์ ์์ฑ์๋ก ์ ๋ฌํด์ผ ํ๋ค. ๋ํ Phone๊ณผ ๋์ผํ๊ฒ ๊ฐ์ ๋ฐํํ ๋ taxRate๋ฅผ ์ด์ฉํด ์ธ๊ธ์ ๋ถ๊ณผํด์ผ ํ๋ค.
public class NightlyDiscountPhone extends PHone {
public NightlyDiscountPhone(Money nightlyAmount, Money regularAmount, Duration seconds, double taxRate) {
super(regularAmount, seconds, taxRate);
...
}
@Override
public Money calculateFee() {
...
return result.minus(nightlyFee.plus(nightlyFee.times(getTaxRate()));
}
}
NightlyDiscountPhone์ Phone์ ์์ ํด๋์ค๋ก ๋ง๋ ์ด์ ๋ Phone์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๊ณ ์ค๋ณต ์ฝ๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด์๋ค. ํ์ง๋ง ์ธ๊ธ์ ๋ถ๊ณผํ๋ ๋ก์ง์ ์ถ๊ฐํ๊ธฐ ์ํด Phone์ ์์ ํ ๋ ์ ์ฌํ ์ฝ๋๋ฅผ NightlyDiscountPhone์๋ ์ถ๊ฐํด์ผ ํ๋ค.
๋ค์ ๋งํด์ ์ฝ๋ ์ค๋ณต์ ์ ๊ฑฐํ๊ธฐ ์ํด ์์์ ์ฌ์ฉํ์์๋ ์ธ๊ธ์ ๊ณ์ฐํ๋ ๋ก์ง์ ์ถ๊ฐํ๊ธฐ ์ํด ์๋ก์ด ์ค๋ณต ์ฝ๋๋ฅผ ๋ง๋ค์ด์ผ ํ๋ ๊ฒ์ด๋ค.
์ด๊ฒ์ NightlyDiscountPhone์ด Phone์ ๊ตฌํ์ ๋๋ฌด ๊ฐํ๊ฒ ๊ฒฐํฉ๋ผ ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ ๋ฌธ์ ๋ค. ์ด์ฒ๋ผ ์์ ๊ด๊ณ๋ก ์ฐ๊ฒฐ๋ ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ๋ณ๊ฒฝ์ ์ทจ์ฝํด์ง๋ ํ์์ ๊ฐ๋ฆฌ์ผ ์ทจ์ฝํ ๊ธฐ๋ฐ ํด๋์ค ๋ฌธ์ ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๋ถ๋ชจ ํด๋์ค์ ์์ ๋ณ๊ฒฝ์๋ ์์ ํด๋์ค๋ ์ปดํ์ผ ์ค๋ฅ์ ์คํ ์๋ฌ๋ผ๋ ๊ณ ํต์ ์๋ฌ๋ ค์ผ ํ ์๋ ์๋ค. ๊ตฌํ์ ์์ํ ๊ฒฝ์ฐ(extends๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ) ํ์ ํด๋์ค๋ ๊ธฐ๋ฐ ํด๋์ค์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋๋ฉฐ, ์ด ๋ ์ฌ์ด์ ๋ฐ์ ํ ์ฐ๊ฒฐ์ ๋ฐ๋์งํ์ง ์๋ค.
์์์ ์์ ํด๋์ค๋ฅผ ์ ์ง์ ์ผ๋ก ์ถ๊ฐํด์ ๊ธฐ๋ฅ์ ํ์ฅํ๋ ๋ฐ๋ ์ฉ์ดํ์ง๋ง ๋์ ๊ฒฐํฉ๋๋ก ์ธํด ๋ถ๋ชจ ํด๋์ค๋ฅผ ์ ์ง์ ์ผ๋ก ๊ฐ์ ํ๋ ๊ฒ์ ์ด๋ ต๊ฒ ๋ง๋ ๋ค. ์ทจ์ฝํ ๊ธฐ๋ฐ ํด๋์ค ๋ฌธ์ ๋ ์บก์ํ๋ฅผ ์ฝํ์ํค๊ณ ๊ฒฐํฉ๋๋ฅผ ๋์ธ๋ค.
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ๊ตฌํ๊ณผ ๊ด๋ จ๋ ์ธ๋ถ์ฌํญ์ ํผ๋ธ๋ฆญ ์ธํฐํ์ด์ค ๋ค๋ก ์บก์ํํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์บก์ํ๋ ๋ณ๊ฒฝ์ ์ํ ํ๊ธํจ๊ณผ๋ฅผ ์ ์ดํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ์น๊ฐ ์๋ค. ๊ฐ์ฒด๋ ๋ณ๊ฒฝ ๋ ์ง๋ ๋ชจ๋ฅด๋ ๋ถ์์ ํ ์์๋ฅผ ์บก์ํํจ์ผ๋ก์จ ํ๊ธํจ๊ณผ๋ฅผ ๊ฑฑ์ ํ์ง ์๊ณ ๋ ์์ ๋กญ๊ฒ ๋ด๋ถ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค.
์์์ ์ฝ๋์ ์ฌ์ฌ์ฉ์ ์ํด ์บก์ํ์ ์ฅ์ ์ ํฌ์์ํค๊ณ ๊ตฌํ์ ๋ํ ๊ฒฐํฉ๋๋ฅผ ๋์์ผ๋ก์จ ๊ฐ์ฒด์งํฅ์ด ๊ฐ์ง ๊ฐ๋ ฅํจ์ ๋ฐ๊ฐ์ํจ๋ค.
java.util.Properties์ java.util.Stack์ ๋ํ์ ์ธ ์๋ชป๋ ์์์ ์์ด๋ค.

์๋ฐ์ ์ด๊ธฐ ์ปฌ๋ ์
ํ๋ ์์ํฌ ๊ฐ๋ฐ์๋ค์ ์์์ ์ถ๊ฐ, ์ญ์ ์คํผ๋ ์ด์
์ ์ ๊ณตํ๋ Vector๋ฅผ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด Stack์ Vector์ ์์ ํด๋์ค๋ก ๊ตฌํํ๋ค.
Vector๋ ์์์ ์์น(index)์์ ์์๋ฅผ ์กฐํํ๊ณ , ์ถ๊ฐํ๊ณ , ์ญ์ ํ ์ ์๋ get, add, remove ์คํผ๋ ์ด์ ์ ์ ๊ณตํ๋ค. ์ด์ ๋นํด Stack์ ๋งจ ๋ง์ง๋ง ์์น ์์๋ง ์์๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ์ ์๋ push, pop ์คํผ๋ ์ด์ ์ ์ ๊ณตํ๋ค.
Stack<String> stack = new Stack<>();
stack.push("1st");
stack.push("2nd");
stack.push("3rd");
stack.add(0, "4th");
assertEquals("4th", stack.pop()); // ์๋ฌ!
์ ์ฝ๋์์ Stack์ ๋ง์ง๋ง์ผ๋ก ์ถ๊ฐํ ๊ฐ์ "4th"์ง๋ง pop ๋ฉ์๋์ ๋ฐํ๊ฐ์ "3rd"๋ค. ๊ทธ ์ด์ ๋ Vector์ add ๋ฉ์๋๋ฅผ ์ด์ฉํด์ ์คํ์ ๋งจ ์์ "4th"๋ฅผ ์ถ๊ฐํ๊ธฐ ๋๋ฌธ์ด๋ค.
์กฐ์์ ๋ธ๋ก์น๋ ํด๋์ค๊ฐ ์์๋๊ธฐ๋ฅผ ์ํ๋ค๋ฉด ์์์ ์ํด ํด๋์ค๋ฅผ ์ค๊ณํ๊ณ ๋ฌธ์ํํด์ผ ํ๋ฉฐ, ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ์๋ ์์์ ๊ธ์ง์์ผ์ผ ํ๋ค๊ณ ์ฃผ์ฅํ๋ค.
๊ทธ๋ฌ๋ ์๋ API ๋ฌธ์๋ ๋ฉ์๋๊ฐ ๋ฌด์จ ์ผ(what)์ ํ๋์ง๋ฅผ ๊ธฐ์ ํด์ผ ํ๊ณ , ์ด๋ป๊ฒ ํ๋์ง(how)๋ฅผ ์ค๋ช ํด์๋ ์ ๋๋ค๋ ํต๋ ์ ์ด๊ธฐ๋ ๊ฒ์ ์๋๊น?
์ด๊ธฐ๋ ๊ฒ์ด๋ค. ์ด ๋ํ ์์์ด ์บก์ํ๋ฅผ ์๋ฐํจ์ผ๋ก์จ ์ด๋๋ ๋ถํ์ธ ๊ฒ์ด๋ค.
์ค๊ณ๋ ํธ๋ ์ด๋์คํ ํ๋์ด๋ผ๋ ์ฌ์ค์ ๊ธฐ์ตํด์ผ ํ๋ค. ์์์ ์ฝ๋ ์ฌ์ฌ์ฉ์ ์ํด ์บก์ํ๋ฅผ ํฌ์ํ๋ค. ์๋ฒฝํ ์บก์ํ๋ฅผ ์ํ๋ค๋ฉด ์ฝ๋ ์ฌ์ฌ์ฉ์ ํฌ๊ธฐํ๊ฑฐ๋ ์์ ์ด์ธ์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํ๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ๊ตฌํ์ด ์๋ ์ถ์ํ์ ์์กดํ๋๋ก ๋ง๋๋ ๊ฒ์ด๋ค. ์ ํํ๊ฒ ๋งํ๋ฉด ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค ๋ชจ๋ ์ถ์ํ์ ์์กดํ๋๋ก ์์ ํด์ผ ํ๋ค. ๊ฐ์ธ์ ์ผ๋ก ์ฝ๋ ์ค๋ณต์ ์ ๊ฑฐํ๊ธฐ ์ํด ์์์ ๋์ ํ ๋ ๋ฐ๋ฅด๋ ๋ ๊ฐ์ง ์์น์ด ์๋ค.
๋ ๋ฉ์๋๊ฐ ์ ์ฌํ๊ฒ ๋ณด์ธ๋ค๋ฉด ์ฐจ์ด์ ์ ๋ฉ์๋๋ก ์ถ์ถํ๋ผ.
๋ถ๋ชจ ํด๋์ค์ ์ฝ๋๋ฅผ ํ์๋ก ๋ด๋ฆฌ์ง ๋ง๊ณ ์์ ํด๋์ค์ ์ฝ๋๋ฅผ ์์๋ก ์ฌ๋ ค๋ผ.
๋ถ๋ชจ ํด๋์ค๋ฅผ ์ถ๊ฐํ์. ๋ชฉํ๋ ๋ชจ๋ ํด๋์ค๋ค์ด ์ถ์ํ์ ์์กดํ๋๋ก ๋ง๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ด ํด๋์ค๋ ์ถ์ ํด๋์ค๋ก ๊ตฌํํ๋ ๊ฒ์ด ์ ํฉํ ๊ฒ์ด๋ค.

๋ชจ๋ ํ์ ํด๋์ค๊ฐ ์ด ํ๋์ ํ ์ ์๊ฒ ๋ง๋ค๋ ค๋ฉด ์ฌ๋ฌ ๊ฐ์ ์ค๋ณต ์ฝ๋๋ฅผ ์์ฐํ๊ฑฐ๋ ์ด ํ๋์ ์์ ํด๋์ค๋ก ์ฌ๋ฆฌ๋ ์๋ฐ์ ์๋ค.
์๊ฐ์ด ํ๋ฅด๊ณ ๊ฐ์ฒด์งํฅ์ ๋ํ ์ดํด๊ฐ ๊น์ด์ง๋ฉด์ ์ฌ๋๋ค์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ๋งน๋ชฉ์ ์ผ๋ก ์์์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ํํ๋ค๋ ์ฌ์ค์ ๊นจ๋ซ๊ธฐ ์์ํ๋ค. ์์์ด ์ฝ๋ ์ฌ์ฌ์ฉ์ด๋ผ๋ ์ธก๋ฉด์์ ๋งค์ฐ ๊ฐ๋ ฅํ ๋๊ตฌ์ธ ๊ฒ์ ์ฌ์ค์ด์ง๋ง ๊ฐ๋ ฅํ ๋งํผ ์๋ชป ์ฌ์ฉํ ๊ฒฝ์ฐ์ ๋์์ค๋ ํผํด ์ญ์ ํฌ๋ค๋ ์ฌ์ค์ ๋ผ์ ๋ฆฌ๊ฒ ๊ฒฝํํ ๊ฒ์ด๋ค.
์์์ ์ค์ฉ๊ณผ ๋จ์ฉ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ดํดํ๊ณ ํ์ฅํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ ๋ค.
์ถ์ฒ
์ค๋ธ์ ํธ - ์ฝ๋๋ก ์ดํดํ๋ ๊ฐ์ฒด์งํฅ ์ค๊ณ
https://github.com/eternity-oop/object