🌻 JAVA/λ””μžμΈ νŒ¨ν„΄

3. λ°μ½”λ ˆμ΄ν„°(Decorator) νŒ¨ν„΄ - Head First Design Patterns

iseunghan 2020. 4. 5. 00:19
λ°˜μ‘ν˜•

컀피 전문점을 μƒκ°ν•΄λ³΄μž.

객체 λ§ˆμ„μ— μŠ€νƒ€λ²„μ¦ˆλΌλŠ” μ»€ν”Όμˆμ΄ μžˆλ‹€.

μ»€ν”Όμ˜ μ’…λ₯˜λŠ” μ—¬λŸ¬κ°€μ§€μ— μΆ”κ°€ν• μˆ˜ μžˆλŠ” 메뉴가 μˆ˜μ‹­κ°€μ§€κ°€ λ μˆ˜λ„ μžˆλ‹€.

λ‹€μŒ 그림을 보자.

κ°„λž΅ν•œ μ„€λͺ…을 μœ„ν•΄ λ‚˜λ¨Έμ§€ ν΄λž˜μŠ€λ“€μ„ μƒλž΅ν–ˆλ‹€.

μ΄λ ‡κ²Œ 클래슀 κ°œμˆ˜κ°€ μ—„μ²­λ‚˜κ²Œ λŠ˜μ–΄λ‚œλ‹€. 컀피 메뉴가 더 λŠ˜μ–΄λ‚˜λ©΄ 훨씬 더 λŠ˜μ–΄λ‚  것이닀.

 

 

상속이 κ°•λ ₯ν•˜κΈ΄ ν•˜μ§€λ§Œ, λͺ¨λ“  μ„œλΈŒ ν΄λž˜μŠ€μ—μ„œλŠ” λ˜‘κ°™μ€ 행동을 μƒμ†λ°›κ²Œ λœλ‹€.

μ΄λŸ΄λ•Œ, ꡬ성을 ν†΅ν•΄μ„œ 행동을 ν™•μž₯ν•˜κ²Œ 되면 싀행쀑에 λ™μ μœΌλ‘œ 행동을 μ„€μ •ν•  μˆ˜μžˆλ‹€. (μŠ€νŠΈλ ˆν‹°μ§€ νŒ¨ν„΄)

 

 

 

λ””μžμΈ 원칙 ) ν΄λž˜μŠ€λŠ” ν™•μž₯에 λŒ€ν•΄μ„œλŠ” μ—΄λ €μžˆμ–΄μ•Ό ν•˜μ§€λ§Œ,

μ½”λ“œ 변경에 λŒ€ν•΄μ„œλŠ” λ‹«ν˜€ μžˆμ–΄μ•Ό ν•œλ‹€.

O.C.P ( Open-Closed Principle)

 

*무쑰건 OCPλ₯Ό μ μš©ν•˜λŠ” 것은 μ‹œκ°„ λ‚­λΉ„κ°€ λ μˆ˜λ„ μžˆλ‹€. μ½”λ“œλ₯Ό ν™•μž₯ν•΄μ•Ό ν•  뢀뢄을 μ„ νƒν• λ•ŒλŠ” μ„Έμ‹¬ν•œ 주의λ₯Ό κΈ°μšΈμ—¬μ•Ό ν•œλ‹€.

 

 

 

컀피 메뉴 쀑 DarkRoast 메뉴λ₯Ό ν•œλ²ˆ μ‚΄νŽ΄ 보자.

DarkRoast 컀피에 Whip, Mochaλ₯Ό μΆ”κ°€ ν•œλ‹€κ³  ν•΄λ³΄μž.

 

λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄μ€ 객체λ₯Ό 감싼닀고 μƒκ°ν•˜λ©΄ λœλ‹€.객체λ₯Ό μž₯μ‹ν•œλ‹€κ³  생각해라.

 

 

cost() λ©”μ†Œλ“œλ‘œ 이 음료λ₯Ό 계산을 ν•΄λ³΄μž.

μ–΄λ–»κ²Œ 이게 κ°€λŠ₯ν•œκ²ƒμΈμ§€, 이따가 μ½”λ“œλ‘œ μ‚΄νŽ΄λ³΄μž.

 

 

 

 

 

λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄ ) 객체의 좔가적인 μš”κ±΄μ„ λ™μ μœΌλ‘œ μ²¨κ°€ν•œλ‹€. λ°μ½”λ ˆμ΄ν„°λŠ” μ„œλΈŒν΄λž˜μŠ€λ₯Ό

λ§Œλ“œλŠ” 것을 톡해 κΈ°λŠ₯을 μœ μ—°ν•˜κ²Œ ν™•μž₯ν•  수 μžˆλŠ” 방법을 μ œκ³΅ν•œλ‹€.

 

 

 

*λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄ : 클래슀 λ‹€μ΄μ–΄κ·Έλž¨   

λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄ : 클래슀 λ‹€μ΄μ–΄κ·Έλž¨

 

 

StarBuzz 컀피 : 클래슀 닀이어 그램

sStarBuzz : 클래슀 λ‹€μ΄μ–΄κ·Έλž¨

 

 

 

 

#μ½”λ“œ

public class HouseBlend extends Beverage {
	public HouseBlend() {
		description = "House Blend Coffee";
	}
 
	public double cost() {
		return .89;
	}
}
public class Mocha extends CondimentDecorator {
	public Mocha(Beverage beverage) { //beverage κ°μ²΄λŠ” μŠˆνΌν΄λž˜μŠ€μ—μ„œ μƒμ†λ°›μ•˜λ‹€.
		this.beverage = beverage;
	}
 
	public String getDescription() {
		return beverage.getDescription() + ", Mocha";
	}
 
	public double cost() {
		return .20 + beverage.cost();
	}
}
public class Soy extends CondimentDecorator {
	public Soy(Beverage beverage) {
		this.beverage = beverage;
	}

	public String getDescription() {
		return beverage.getDescription() + ", Soy";
	}

	public double cost() {
		return .15 + beverage.cost();
	}
}
// main μ½”λ“œ

Beverage beverage = new HouseBlend();
beverage = new Mocha(beverage);
beverage = new Soy(beverage);
// 음료 이름과 가격 좜λ ₯.
System.out.println( beverage.getDescription() + "$" + beverage.cost() );
Beverage beverage = new HouseBlend();
//μ—¬κΈ°μ„œ HouseBlend의 μƒμ„±μžκ°€ 호좜이 λœλ‹€. description에 Houseblendκ°€ μ €μž₯되고,
//μΈμŠ€ν„΄μŠ€ λ³€μˆ˜κ°€ λ©”λͺ¨λ¦¬μ— μ˜¬λΌκ°€κ²Œ λœλ‹€.

berverge = new Mocha(beverage);
//Mocha μƒμ„±μžμ— λ§€κ°œλ³€μˆ˜λ‘œ HouseBlend객체λ₯Ό λ„˜κ²¨μ€€λ‹€. 그럼 beverage에 HouseBlend객체가 μ €μž₯λœλ‹€.

beverage = new Soy(beverage);
//Soy μƒμ„±μžμ— λ§€κ°œλ³€μˆ˜λ‘œ Mocha객체λ₯Ό λ„˜κ²¨μ€€λ‹€. 그럼 beverage에 Mocha객체가 μ €μž₯λœλ‹€.

//이제 beverage.cost() λ₯Ό ν˜ΈμΆœν•˜κ²Œ 되면-
//λ§ˆμ§€λ§‰μ— μ €μž₯된 객체가 Soy μ΄λ―€λ‘œ Soy.cost()κ°€ 호좜이 λœλ‹€.

/*
(μ‹€ν–‰λ˜λŠ” μˆœμ„œ)	  1. Soy.cost() -> 2. Mocha.cost() -> 3. HouseBlend.cost()
------------------------------------------------------------------------------
	1.  0.15 + (Mocha)beverage.cost()
        2.  0.20 + 0.15 + (HouseBlend)beverage.cost()
        3.  0.99 + 0.22 + 0.15
*/

 

λ°˜μ‘ν˜•