[Daily] DI / DIP
๐ง DI (Dependency Injection)๋?
DI(์์กด์ฑ ์ฃผ์ )์ ๊ฐ์ฒด๊ฐ ์ง์ ํ์ํ ์์กด ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๊ณ , ์ธ๋ถ์์ ์ฃผ์ ๋ฐ๋ ๋ฐฉ์
๐ ์: โ์๋์ฐจ(Car)โ์ โ์์ง(Engine)โ์ด ํ์ํ ๋
โ ์ง์ ์์ฑ (์์กด์ฑ ์ง์ ๊ด๋ฆฌ)
class Car {
private Engine engine = new Engine();
// Car๊ฐ ์ง์ Engine์ ์์ฑํจ
}
โ ์์กด์ฑ ์ฃผ์ ๋ฐฉ์
class Car {
private Engine engine;
public Car(Engine engine) { // ์ธ๋ถ์์ Engine์ ์ฃผ์
๋ฐ์
this.engine = engine;
}
}
์ด๋ ๊ฒ ํ๋ฉด Car๋ ์ด๋ค ์ข ๋ฅ์ ์์ง์ด ๋ค์ด์ค๋์ง ๋ชฐ๋ผ๋ ๋๊ณ , ํ ์คํธ๋ ๋ ์ ์ฐํ๊ฒ ํ ์ ์๋ค.
๐งฉ ์ฃผ์ ์ฉ์ด ์ ๋ฆฌ
์ฉ์ด | ์ค๋ช |
---|---|
Dependency (์์กด์ฑ) | ํ ๊ฐ์ฒด๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ์ผ๋ก ์์กดํ๊ณ ์์ ๋, ๊ทธ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ โ์์กด์ฑโ์ด๋ผ๊ณ ๋ถ๋ฆ. ์: Car โ Engine |
Injection (์ฃผ์ ) | ์์กด ๊ฐ์ฒด๋ฅผ ์ง์ ์์ฑํ์ง ์๊ณ , ์ธ๋ถ์์ ๋ฃ์ด์ฃผ๋ ํ์ |
DI Container | ์์กด์ฑ๋ค์ ๊ด๋ฆฌํ๊ณ ์ฃผ์
ํด์ฃผ๋ ์ปจํ
์ด๋. Spring์ ApplicationContext ๊ฐ ๋ํ์ |
Constructor Injection | ์์ฑ์๋ฅผ ํตํด ์์กด์ฑ์ ์ฃผ์ (๊ฐ์ฅ ๊ถ์ฅ๋๋ ๋ฐฉ์) |
Setter Injection | setter ๋ฉ์๋๋ฅผ ํตํด ์์กด์ฑ ์ฃผ์ |
Field Injection | ํ๋์ ์ง์ ์ฃผ์
(@Autowired ๋ฑ). ๊ฐ๋จํ์ง๋ง ํ
์คํธ ์ด๋ ค์ |
IoC (Inversion of Control) | โ์ ์ด์ ์ญ์ โ โ ๊ฐ์ฒด์ ์์ฑ๊ณผ ์๋ช ์ฃผ๊ธฐ ๊ด๋ฆฌ๋ฅผ ๊ฐ๋ฐ์๊ฐ ์๋๋ผ ํ๋ ์์ํฌ๊ฐ ๋ด๋นํ๋ ๊ฐ๋ . DI๋ IoC๋ฅผ ๊ตฌํํ๋ ํ ๋ฐฉ์ |
๐๏ธ DI๋ฅผ ์ฌ์ฉํ๋ ์ด์
- ๊ฒฐํฉ๋ ๋ฎ์ถค โ ์ฝ๋๊ฐ ๋ ์ ์ฐํ๊ณ ํ์ฅ ๊ฐ๋ฅ
- ํ ์คํธ ์ฌ์ โ ๊ฐ์ง(Mock) ๊ฐ์ฒด ์ฃผ์ ํด์ ๋จ์ ํ ์คํธ ๊ฐ๋ฅ
- ์ ์ง๋ณด์ ํธ๋ฆฌ โ ์๋ก์ด ์์กด์ฑ์ผ๋ก ์ฝ๊ฒ ๊ต์ฒด ๊ฐ๋ฅ
- ๊ด์ฌ์ฌ ๋ถ๋ฆฌ โ ๊ฐ์ฒด๋ ์์ ์ ๋ก์ง์๋ง ์ง์คํ๊ณ ์์กด์ฑ ๊ด๋ฆฌ๋ ์ธ๋ถ์ ๋งก๊น
๐ ์์ฃผ ํจ๊ป ์ธ๊ธ๋๋ ๊ฐ๋
๊ฐ๋ | ์ค๋ช |
---|---|
Service, Repository ๋ฑ ์ญํ ๋ถ๋ฆฌ | DI๋ฅผ ํตํด ๊ฐ ๊ณ์ธต ๊ฐ ๊ฒฐํฉ์ ๋์จํ๊ฒ ๋ง๋ค ์ ์์ |
@Component, @Service, @Repository | Spring์ด ์๋์ผ๋ก Bean์ผ๋ก ๋ฑ๋กํด์ DI ๊ฐ๋ฅํ๊ฒ ํจ |
@Autowired, @Inject, @Qualifier | ์์กด์ฑ์ ์ฃผ์ ํ๋ ๋ฐฉ๋ฒ๊ณผ ์กฐ๊ฑด์ ์ง์ ํจ |
๐ง Spring์์์ DI ์์
๐ฏ ๋ชฉํ
Car
๊ฐEngine
์ ์์กด- ๋ค์ํ ๋ฐฉ์์ผ๋ก Engine์ ์ฃผ์ (DI)
- DI๋ฅผ ํตํด Car๋ ์ด๋ค Engine์ด๋ ๋ฐ์์ ์ธ ์ ์๋๋ก ์ค๊ณ
๐น ์ธํฐํ์ด์ค ๋ฐ ๊ตฌํ์ฒด
public interface Engine {
void start();
}
@Component
public class GasEngine implements Engine {
@Override
public void start() {
System.out.println("Gas engine starting...");
}
}
@Component
public class ElectricEngine implements Engine {
@Override
public void start() {
System.out.println("Electric engine starting...");
}
}
๐น Car ํด๋์ค (DI ์ ์ฉ)
๋ฐฉ๋ฒ 1: ์์ฑ์ ์ฃผ์ (๊ฐ์ฅ ๊ถ์ฅ๋จ)
@Component
public class Car {
private final Engine engine;
@Autowired // ์๋ต ๊ฐ๋ฅ (Spring 4.3 ์ด์)
public Car(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is moving");
}
}
๋ฐฉ๋ฒ 2: ํ๋ ์ฃผ์ (ํ ์คํธ ๋ถํธ, ๋น๊ถ์ฅ)
@Component
public class Car {
@Autowired
private Engine engine;
public void drive() {
engine.start();
System.out.println("Car is moving");
}
}
๋ฐฉ๋ฒ 3: Setter ์ฃผ์ (์ ํ์ ์์กด์ฑ์ ์ ํฉ)
@Component
public class Car {
private Engine engine;
@Autowired
public void setEngine(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is moving");
}
}
๐ง ํ๋ ์ฃผ์ ์ด ํ ์คํธ์์ ๋ถํธํ ์ด์
โ ๋ฌธ์ : ์ฃผ์ ์ ์ง์ ํ ์ ์๋ค
ํ๋ ์ฃผ์
์ ์๋์ฒ๋ผ private
ํ๋์ @Autowired
๋ฅผ ๋ถ์ฌ ์๋ ์ฃผ์
@Component
public class Car {
@Autowired
private Engine engine;
public void drive() {
engine.start();
}
}
์ด๋ฐ ๊ฒฝ์ฐ ํ
์คํธ ์ฝ๋์์ ์ง์ engine
์ ์ฃผ์
ํ ์ ์๋ค
Car car = new Car();
๋ก ์์ฑํด๋engine
์ดnull
engine
์ ์ฃผ์ ํ๋ ค๋ฉด ๋ฆฌํ๋ ์ ์ ์จ์ผ ํจ:
@Test
void testDrive_withReflection() throws Exception {
Car car = new Car();
Engine mockEngine = mock(Engine.class);
Field field = Car.class.getDeclaredField("engine");
field.setAccessible(true);
field.set(car, mockEngine); // ๊ฐ์ ๋ก ์ฃผ์
car.drive();
}
โ ์์ฑ์ ์ฃผ์ ๊ณผ ๋น๊ต
์์ฑ์ ์ฃผ์ ์ด๋ฉด, ๋ค์๊ณผ ๊ฐ์ด ์ฝ๊ฒ ํ ์คํธ ๊ฐ๋ฅ:
@Test
void testDrive() {
Engine mockEngine = mock(Engine.class);
Car car = new Car(mockEngine); // ์ง์ ์ฃผ์
๊ฐ๋ฅ
car.drive();
verify(mockEngine).start(); // ๊ฒ์ฆ๋ ๊ฐ๋ฅ
}
๐ก ํ๋ ์ฃผ์ ์ ๋ค๋ฅธ ๋จ์
ํญ๋ชฉ | ๋ด์ฉ |
---|---|
โ ๋ถ๋ณ์ฑ ์์ | ์์ฑ ์์ ์ ์ฃผ์ ๋์ง ์์์ final ํค์๋ ๋ชป ์ |
โ ๋ช ์์ ์์กด์ฑ ์์ | ์ด๋ค ์์กด์ฑ์ด ํ์ํ์ง ์์ฑ์ ์๊ทธ๋์ฒ๋ก๋ ์ ์ ์์ |
โ ํ ์คํธ ์ด๋ ค์ | ์์์ ๋ณธ ๊ฒ์ฒ๋ผ mock ์ฃผ์ , ์์กด์ฑ ๊ต์ฒด๊ฐ ์ด๋ ต๊ณ ์ฐํ์ |
โ ์ ์ง๋ณด์ ์ด๋ ค์ | ์ฝ๋๋ง ๋ณด๊ณ ๋ ์ด๋ค ๊ฐ์ฒด๊ฐ ๋ค์ด์ค๋์ง ์ถ๋ก ์ด ์ด๋ ค์ |
ย | ย |
โ ์ ๋ฆฌ
- ํ๋ ์ฃผ์ ์ ํธ๋ฆฌํด ๋ณด์ด์ง๋ง, ์ ๋ ํ ์คํธ, ๋ถ๋ณ์ฑ, ๋ช ์์ฑ ์ธก๋ฉด์์ ๋ชจ๋ ๋ถ๋ฆฌํจ
- ๊ทธ๋์ Spring ๊ณต์ ๊ฐ์ด๋, Josh Long ๊ฐ์ ์ ๋ฌธ๊ฐ๋ค๋ โํญ์ ์์ฑ์ ์ฃผ์ ์ ์ฐ๋ผโ๊ณ ๊ถ์ฅ ํจ
- ํ ์คํธ์์๋ ํนํ mock ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํ๊ธฐ ์ด๋ ค์์ ์ ๋ง ๋ถํธํจ
โ Setter ์ฃผ์ ์ด โ์ ํ์ ์์กด์ฑโ์ ์ ํฉํ ์ด์
์ด๋ค ์์กด์ฑ์ ์์ผ๋ฉด ์ข์ง๋ง, ์์ด๋ ๋์์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ โ ๊ผญ ์์ฑ์์ ๋ฃ์ ํ์๊ฐ ์์
โ ๊ทธ๋์ setter๋ก ํ์ํ ๋๋ง ์ฃผ์ ํ๋๋ก ์ค๊ณ
@Component
public class MyService {
private Logger logger;
@Autowired(required = false) // ์ฃผ์
์ ๋ผ๋ ์ค๋ฅ ์ ๋จ
public void setLogger(Logger logger) {
this.logger = logger;
}
public void doSomething() {
if (logger != null) {
logger.log("Starting...");
}
System.out.println("Doing something important!");
}
}
Logger
๋ ์์ด๋ ๋ก์ง์ ๋์๊ฐ- ์์ ๊ฒฝ์ฐ์๋ง ๋ก๊น ์ํ
- ๋ฐ๋ผ์ Setter ์ฃผ์ ์ด ์ ํฉ
โ Setter ์ฃผ์ ์ ์ฅ์
ํญ๋ชฉ | ์ค๋ช |
---|---|
โ ์ ํ์ ์์กด์ฑ ํํ ๊ฐ๋ฅ | @Autowired(required = false) ๋ก ์์ผ๋ฉด ์ฃผ์
, ์์ผ๋ฉด ๋์ด๊ฐ |
โ ๋์ค์ ๋ฐ๊ฟ ์ ์์ | Bean ์์ฑ ์ดํ ๋ค๋ฅธ ๊ฐ์ฒด๋ก๋ ์ฃผ์ ๊ฐ๋ฅ (๋์ ์ผ๋ก ๋ฐ๊พธ๊ณ ์ถ์ ๋) |
โ ํ ์คํธ์์ mock ์ฝ๊ฒ ์ฃผ์ ๊ฐ๋ฅ | setLogger(mockLogger) ์ฒ๋ผ ์ฃผ์
๊ฐ๋ฅ |
โ Setter ์ฃผ์ ์ ๋จ์
ํญ๋ชฉ | ์ค๋ช |
---|---|
โ ๋ถ๋ณ ๊ฐ์ฒด ์ค๊ณ ๋ถ๊ฐ | setter๋ ๊ฐ ๋ณ๊ฒฝ ํ์ฉ โ ์ํ๊ฐ ๋ฐ๋ ์ ์์ |
โ ์์กด์ฑ ๋๋ฝ ๋ฐฉ์ง ์ด๋ ค์ | ์ฃผ์ ์ ๊น๋นกํด๋ ์ปดํ์ผ๋ฌ๊ฐ ์ ์ก์ (๋ฐํ์ ์ค๋ฅ ์ ๋ฐ ๊ฐ๋ฅ) |
โ ๋ช ์์ ์์กด์ฑ ํํ ์ฝํจ | ํด๋์ค๋ง ๋ณด๊ณ ๋ ํ์์ธ์ง ์ ํ์ธ์ง ๋ฐ๋ก ํ์ ์ด๋ ค์ |
โ ๋น๊ต ์์ฝ
๊ตฌ๋ถ | ์์ฑ์ ์ฃผ์ | Setter ์ฃผ์ | ํ๋ ์ฃผ์ |
---|---|---|---|
๐ ์ฉ๋ | ํ์ ์์กด์ฑ | ์ ํ์ ์์กด์ฑ | ๊ฐ๋ณ๊ฒ ์ฐ๊ธฐ ์ฌ์ (but ๋น๊ถ์ฅ) |
๐ ๋ถ๋ณ์ฑ | ์ ์ง ๊ฐ๋ฅ | ์ ์ง ๋ถ๊ฐ | ์ ์ง ๋ถ๊ฐ |
๐ ํ ์คํธ ์ฉ์ด์ฑ | ๋งค์ฐ ์ข์ | ์ข์ | ๋์จ |
๐งฉ ๋ช ์์ฑ | ๋์ | ๋ฎ์ | ๋ฎ์ |
๐ ์ ๋ฆฌ
- Setter ์ฃผ์ ์ โํ์๋ ์๋, ์ต์ ์ ์ธโ ์์กด์ฑ์ ์ฃผ์ ํ ๋ ์ฌ์ฉ
- ๊ทธ ์ธ์๋ ๋๋ถ๋ถ ์์ฑ์ ์ฃผ์ ์ด ์ ์
- Spring์์๋ setter ์ฃผ์ ๋ ๊ฐ๋ฅํ์ง๋ง, ๋ฌด๋ถ๋ณํ๊ฒ ์ฌ์ฉํ๋ฉด **์ค๊ณ๊ฐ ๋ชจํธํด์ง๊ณ ์ ์ง๋ณด์ ์ด๋ ค์์ง
๐ง 2. DIP (Dependency Inversion Principle)
๐ DIP๋?
์์กด์ฑ ์ญ์ ์์น:
โ์์ ๋ชจ๋(๋น์ฆ๋์ค ๋ก์ง)์ ํ์ ๋ชจ๋(๊ตฌํ)์ ์์กดํด์๋ ์ ๋๋ฉฐ,
๋ ๋ค ์ถ์(์ธํฐํ์ด์ค)์ ์์กดํด์ผ ํ๋ค.โ
โ DIP ์๋ฐ ์
public class Car {
private GasEngine engine = new GasEngine();
// ๊ตฌํ์ฒด์ ์์กด (๊ฐํ ๊ฒฐํฉ)
}
Car
๋ GasEngine
์ด๋ผ๋ ๊ตฌ์ฒด ํด๋์ค์ ์์กด โ ํ์ฅ์ฑ ๋ฎ๊ณ , ํ
์คํธ ์ด๋ ค์
โ DIP ๋ง์กฑ ์
public class Car {
private Engine engine;
public Car(Engine engine) { // ์ธํฐํ์ด์ค(์ถ์)์ ์์กด
this.engine = engine;
}
}
Car
๋ Engine
์ด๋ผ๋ ์ถ์ ํ์
์๋ง ์์กด โ ์ ์ฐํ๊ณ ํ
์คํธ ์ฉ์ด
โ
1. Engine
์ถ์ํ(์ธํฐํ์ด์ค) ์ ์
public interface Engine {
void start();
}
Engine
์ ์ธํฐํ์ด์ค์ด๋ฏ๋ก โํ์(๊ธฐ๋ฅ)โ๋ง ์ ์Car
๋ ์ด์ ์ด ์ถ์ ํ์ ๋ง ์๋ฉด ๋จ
โ
2. GasEngine
๊ตฌํ์ฒด ์ ์ (DIP ๋ง์กฑ)
public class GasEngine implements Engine {
@Override
public void start() {
System.out.println("Gas engine started.");
}
}
GasEngine
์Engine
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค- ์ด ๊ตฌํ์ฒด๋ ์ค์ ๊ธฐ๋ฅ์ ์ํํ๋ ํด๋์ค
โ
3. Car
ํด๋์ค๋ ์ถ์ํ์๋ง ์์กด
public class Car {
private final Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
}
}
- ์ด์
Car
๋ ๋ ์ด์GasEngine
์ด ๋ญ์ง ๋ชฐ๋ผ๋ ๋จ - ์ค์ง
Engine
์ธํฐํ์ด์ค๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ฅ(start()
)๋ง ์ฌ์ฉ
โ 4. ์ฌ์ฉํ๋ ์ชฝ์์ ์ฃผ์ (DI)
public class Main {
public static void main(String[] args) {
Engine engine = new GasEngine(); // ์ด๋ค ๊ตฌํ์ฒด๋ฅผ ์ธ์ง๋ ์ฌ๊ธฐ์ ๊ฒฐ์
Car car = new Car(engine);
car.drive(); // "Gas engine started." ์ถ๋ ฅ
}
}
Car
๋Engine
ํ์ ์ ๋ฐ์์ ์ฌ์ฉํ๋ฏ๋ก DIP ๋ง์กฑ- ๊ตฌํ์ฒด(
GasEngine
,ElectricEngine
๋ฑ)๋ ์ฃผ์ ์ ํตํด ๊ต์ฒด ๊ฐ๋ฅ
โ ํ ์คํธ๋ ์ฌ์์ง (๋ชจ์ ๊ฐ์ฒด)
public class MockEngine implements Engine {
public boolean started = false;
@Override
public void start() {
started = true;
}
}
@Test
void testCarDrives() {
MockEngine mock = new MockEngine();
Car car = new Car(mock);
car.drive();
assertTrue(mock.started);
}
๐ก ํต์ฌ ์์ฝ
๊ตฌ๋ถ | DIP ์๋ฐ | DIP ๋ง์กฑ |
---|---|---|
์์กด์ฑ | GasEngine ์ง์ ์์ฑ |
Engine ์ธํฐํ์ด์ค ์ฃผ์
|
๊ฒฐํฉ๋ | ๋์ (๋ณ๊ฒฝ ์ด๋ ค์) | ๋ฎ์ (์ ์ฐํจ) |
ํ ์คํธ | ์ด๋ ค์ (Mock ๋ถ๊ฐ) | ์ฌ์ (์ธํฐํ์ด์ค๋ก ๋์ฒด ๊ฐ๋ฅ) |
ํ์ฅ์ฑ | GasEngine ๋ง ๊ฐ๋ฅ |
ElectricEngine ๋ฑ ๋ค๋ฅธ ์์ง๋ ๊ฐ๋ฅ |
๐ DIP vs DI ์ฐจ์ด
๊ฐ๋ | ์ค๋ช |
---|---|
DIP (์์น) | ์ค๊ณ ์์น. โ์ถ์ํ์ ์์กดํ๋ผ, ๊ตฌํ์ ์์กดํ์ง ๋ง๋ผ.โ |
DI (๊ธฐ์ ) | ๊ตฌํ ๊ธฐ์ . โ์์กด ๊ฐ์ฒด๋ฅผ ์ธ๋ถ์์ ์ฃผ์ ํด๋ผ.โ (์ด ์์น์ ์คํํ๋ ๋ฐฉ๋ฒ ์ค ํ๋) |
์ฆ, DI๋ DIP๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ์๋จ ์ค ํ๋๋ค.
โ DIP(์์กด์ฑ ์ญ์ ์์น) ํต์ฌ ์ ๋ฆฌ
์์ ๋ชจ๋(์ ์ฑ )์ด ํ์ ๋ชจ๋(๊ตฌํ)์ ์์กดํ์ง ๋ง๊ณ ,
๋ ๋ค ์ถ์ํ(์ธํฐํ์ด์ค)์ ์์กดํ๋ผ๋ ์์น.
๐ DIP๋ฅผ ์ ๋๋ก ์ดํดํ๊ธฐ ์ํด ๊ผญ ์์์ผ ํ ์ถ๊ฐ ๊ฐ๋ ๋ค
1. ์์/ํ์ ๋ชจ๋์ด ๋ญ๋?
- ์์ ๋ชจ๋: ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง, ๊ท์น, ์ ์ฑ
๋ฑ (์:
OrderService
) - ํ์ ๋ชจ๋: ๊ตฌ์ฒด์ ์ธ ๊ตฌํ (์:
MemoryOrderRepository
,JdbcOrderRepository
)
// DIP ์๋ฐ (์์๊ฐ ํ์์ ์ง์ ์์กด)
public class OrderService {
private MemoryOrderRepository repository = new MemoryOrderRepository();
}
// DIP ๋ง์กฑ (์์๋ ํ์๋ ์ธํฐํ์ด์ค์ ์์กด)
public class OrderService {
private final OrderRepository repository;
public OrderService(OrderRepository repository) {
this.repository = repository;
}
}
2. DIP๋ฅผ ์ ์ฉํ๋ฉด ์ป๋ ์ค์ง์ ์ด์
์ด์ | ์ค๋ช |
---|---|
โ ํ์ฅ์ฑ | ์๋ก์ด ๊ตฌํ์ฒด๋ฅผ ์ฝ๊ฒ ๋ถ์ผ ์ ์์ (RedisRepo , MongoRepo ๋ฑ) |
โ ํ ์คํธ ์ฉ์ด | FakeRepo , MockRepo ๋ฅผ ๋ฐ๋ก ์ฃผ์
ํด์ ํ
์คํธ ๊ฐ๋ฅ |
โ ์ ์ง๋ณด์ ํธ์ | ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๊ตฌํ์ด ๋ถ๋ฆฌ๋์ด ๋ณ๊ฒฝ ์ํฅ โ |
โ ์์กด ๋ฐฉํฅ ๋ช ํ | ์์ ์ ์ฑ ์ด ๊ตฌํ ์ธ๋ถ์ฌํญ์ ๋๋ ค๊ฐ์ง ์์ |
3. DIP๋ SRP(๋จ์ผ ์ฑ ์ ์์น)์ ์ง์ด๋ค
- DIP๋ ๋จ์ผ ์ฑ ์ ์์น(SRP)๊ณผ ํจ๊ป โ์ญํ ๊ณผ ๊ตฌํ์ ๋ถ๋ฆฌโํ๋ ์ค๊ณ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด์ค์ผํจ.
- ์:
OrderService
๋ โ์ฃผ๋ฌธ ์ฒ๋ฆฌโ๋ผ๋ ์ญํ ๋ง ์ง์คํ๊ณ , ์ ์ฅ ๋ฐฉ์์ ๊ด์ฌ ์์.
4. DIP๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ DI
- DIP๋ ์ค๊ณ ์์น์ด๊ณ ,
- DI(Dependency Injection)๋ ๊ทธ๊ฑธ ๊ตฌํํ๋ ๊ธฐ์ /ํจํด
- Spring์ DI๋ฅผ ํตํด DIP๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ์คํํ๊ฒ ํด์ค๋ค.
๐ DIP๋ฅผ ์ ๋๋ก ์ดํดํ๋ ค๋ฉด:
- ๋จ์ํ โ์ธํฐํ์ด์ค ์จ์ผ ํ๋คโ๋ ์์ค์ ๋์ด์์,
- โ์์กด ๋ฐฉํฅ์ด ์ถ์ํ๋ก ํฅํ๋๋ก ์ค๊ณํ๋ ๊ฒโ์ด ํต์ฌ์ด๊ณ ,
- DI๋ ๊ทธ๊ฑธ ๋์์ฃผ๋ ๊ธฐ์ ์ด๋ผ๋ ์ ์ ์ดํดํด์ผ ํ๋ค.
๋๊ธ๋จ๊ธฐ๊ธฐ