Strategy Pattern

ν˜Έλ–‘Β·2022λ…„ 10μ›” 11일
1

πŸ’‘ Spring FrameWork νŒŒμƒ κ°œλ…


μ „λž΅ νŒ¨ν„΄μ΄λž€ 각각의 μ•Œκ³ λ¦¬μ¦˜μ„ κ΅ν™˜μ΄ κ°€λŠ₯ν•˜λ„λ‘ μ •μ˜, μΊ‘μŠν™”λ₯Ό ν•œ λ‹€μŒ, μ„œλ‘œ κ΅ν™˜ν•΄μ„œ μ‚¬μš©ν•  수 μžˆλŠ” νŒ¨ν„΄μ΄λ‹€. 즉, 객체듀이 ν•  수 μžˆλŠ” λ™μž‘μ„ 각각의 μ „λž΅μœΌλ‘œ λ§Œλ“€μ–΄ 놓고 λ™μ μœΌλ‘œ λ™μž‘μ„ λ³€κ²½ν•΄μ•Ό ν•œλ‹€λ©΄ μ „λž΅λ§Œ λ³€κ²½ν•˜μ—¬ λ™μž‘μ΄ λ°”λ€Œλ„λ‘ ν•˜λŠ” νŒ¨ν„΄μ΄λ‹€.
⭐ λŠμŠ¨ν•œ κ²°ν•©κ³Ό μ œμ–΄μ˜ μ—­μ „ 적용


μ „λž΅ νŒ¨ν„΄(Strategy Pattern)

μ „λž΅ νŒ¨ν„΄μ€ κΈ°λŠ₯듀이 쀑볡 κ΅¬ν˜„λ˜λŠ” 것을 막기 μœ„ν•΄ μ—¬λŸ¬ 가지 κΈ°λŠ₯을 κΈ°λŠ₯λ³„λ‘œ λ‚˜λˆ„μ–΄ ν•˜λ‚˜μ˜ 덩어리(클래슀)둜 λ§Œλ“ λ‹€. 이둜써 μ „λž΅(κΈ°λŠ₯)을 κ°œλ³„ 객체에 맞게 μ—¬λŸ¬ κ°€μ§€λ‘œ μ‘°ν•©ν•˜μ—¬ μ‚¬μš©ν•  수 있게 ν•΄μ€€λ‹€. ν…œν”Œλ¦Ώ λ©”μ†Œλ“œ νŒ¨ν„΄μœΌλ‘œλŠ” μœ„μ˜ 그림을 κ΅¬ν˜„ν•΄λ‚Ό 수 μ—†λ‹€. μ „λž΅ νŒ¨ν„΄μ€ Spring의 DIλ₯Ό μ •ν™•νžˆ ν‘œν˜„ν•œλ‹€.


μ „λž΅ νŒ¨ν„΄μ˜ μ™„μ„±

두 가지 μ˜μ‘΄μ„±μ„ μ™„ν™”μ‹œν‚΄μœΌλ‘œμ¨ μ „λž΅ νŒ¨ν„΄μ΄ μ™„μ„±λœλ‹€.
1. 객체 생성 μ˜μ‘΄μ„± : IoCν•¨μœΌλ‘œμ¨ ν•΄μ†Œ κ°€λŠ₯
2. νƒ€μž… μ˜μ‘΄μ„± : Interfaceλ₯Ό ν™œμš©ν•¨μœΌλ‘œμ¨ λŠμŠ¨ν•œ 결합을 ν•˜μ—¬ ν•΄μ†Œ κ°€λŠ₯


이 λ•Œ 객체 생성 μ˜μ‘΄μ„±κ³Ό κ΄€λ ¨ν•˜μ—¬ 'μ˜μ‘΄μ„± μ£Όμž…' λ°©λ²•μ—λŠ” 두 가지 방법이 μžˆλ‹€.
1) μƒμ„±μžμ— 객체λ₯Ό λ„£μ–΄μ£Όλ©΄ Constructor Injection
2) μ„€μ •μžμ— 객체λ₯Ό λ„£μ–΄μ£Όλ©΄ Property Injection/Setter Injection

// μ½”λ“œλ‘œ μ‚΄νŽ΄λ³΄λ©΄ μ•„λž˜μ™€ κ°™λ‹€.
public class Test {
	public static void main(String[] args) {
		//work에 λŒ€ν•œ μ˜μ‘΄μ„±μ΄ Employeeμ—μ„œ Test둜 이관됨.
		//이것이 IoC (μ œμ–΄μ˜ μ—­μ „)
		DoWork work = new DoWork();
		//Testκ°€ μƒμ„±ν•œ work 객체λ₯Ό Employee에 λ„£μ–΄μ€Œ
		//이것이 DI (μ˜μ‘΄μ„± μ£Όμž…)
		Person employee = new Employee(work);
		p.daily();
	}
}

예제

public interface DoSomething {
	public void doSomething();
}
public class DoStudy implements DoSomething{
	@Override
	public void doSomething() {
		System.out.println("κ³΅λΆ€ν•œλ‹€.");
	}
}
public class DoWork implements DoSomething {
	@Override
	public void doSomething() {
		System.out.println("μ†Œμ™€ 같이 일을 ν•œλ‹€.");
	}
}
public interface Eating {
	public void eat();
}
public class EatCafeteria implements Eating{
	@Override
	public void eat() {
		System.out.println("급식을 λ¨ΉλŠ”λ‹€.");
	}
}
public class EatWellStory implements Eating{
	@Override
	public void eat() {
		System.out.println("μ›°μŠ€ν† λ¦¬λ₯Ό λ¨ΉλŠ”λ‹€.");
	}
}
public class Person {
	private String name;
    
	private DoSomething doSomething;
	private Eating eating;
    
	public void setDoSomething(DoSomething doSomething) {
		this.doSomething = doSomething;
	}
	public void setEating(Eating eating) {
		this.eating = eating;
	}
	
	public void daily() {
		System.out.println("μž…μ‹€μ²΄ν¬λ₯Ό ν•œλ‹€.");
		doSomething.doSomething();
		eating.eat();
		System.out.println("퇴싀체크λ₯Ό ν•œλ‹€.");
	}
}
public class PersonFactory {
	// μ œμ–΄μ˜ μ—­μ „
	static DoSomething work = new DoWork();
	static DoSomething study = new DoStudy();
	static Eating cafeteria = new EatCafeteria();
	static Eating wellStory = new EatWellStory();

	public static Person getInstance(String type) {
		Person p = new Person();
		switch (type) {
		case "Employee":
        	// μ˜μ‘΄μ„± μ£Όμž…(의쑴 관계 μ—°κ²°)_Setter Injection
			p.setDoSomething(work);
			p.setEating(wellStory);
			break;

		case "Student":
			p.setDoSomething(study);
			p.setEating(cafeteria);
			break;
		case "SSAFY":
			p.setDoSomething(study);
			p.setEating(wellStory);
			break;
		}
		return p;
	}
}
πŸ“Œ μ œμ–΄μ˜ 역전을 ν•œ 곳에 λͺ°μ•„λ„£μ–΄ ν•œ κ³³μ—μ„œλ§Œ λͺ¨λ“  new 객체 생성이 μΌμ–΄λ‚œλ‹€. κ·Έ ν•œ 
곳은 PersonFactory이며, Spring에선 '객체 관리 μ»¨ν…Œμ΄λ„ˆ'이닀. 이 κ³³μ—μ„œ Spring은 
객체 생성, μ˜μ‘΄κ΄€κ³„ 연결을 (μ„€μ •λ§Œ ν•΄μ£Όλ©΄) μ±…μž„μ§€κ³  μ‹€ν–‰ν•œλ‹€.
πŸ“Œ μΈν„°νŽ˜μ΄μŠ€λ‘œ 좔상화λ₯Ό μ‹œν‚€λ©΄ κ·Έ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 객체듀은 μ–΄λ–€ 것이든 ν•΄λ‹Ή 
μΈν„°νŽ˜μ΄μŠ€μ— λŒ€μž… κ°€λŠ₯ν•˜λ‹€. λŠμŠ¨ν•œ 결합을 ν•˜μ—¬ νƒ€μž… μ˜μ‘΄μ„±μ„ ν•΄μ†Œν•œ 것이닀.

0개의 λŒ“κΈ€