CC E23 Mocking Part2์ ๋์ด
humble object pattern์ 2๊ฐ์ง ๊ด์ ์์ ๋ฐ๋ผ ๋ณผ ์ ์๋ค.
-
H/W ๋ฑ ๊ตฌ์ฒด์ ์ธ ์ฝ๋์ ์์กดํ๋ ์ดํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์
- ๋ด ๋ก์ง์์ H/W ์์กด์ ์ธ ๋ถ๋ถ์ Humble Interface๋ฅผ ํตํด ๋ถ๋ฆฌํ๊ณ ๋ด ๋ก์ง์ Unit Test
-
์๋ฒ ๋ก์ง์ ์์กดํ๋ UI ๊ฐ๋ฐ์(App, Web Front)
- GUI์์ Process Interface(Humble Interface)๋ฅผ ๋ถ๋ฆฌํ๊ณ Fake ๊ตฌํ์ฒด๋ฅผ ์ถ๊ฐํ๊ณ
- ๋ด ๋ก์ง(GUI)์ ์๋์ผ๋ก ํ ์คํธํ ์ ์๋ ๋งํผ Humbleํ๊ฒ ์ ์ง
1์ ๊ฒฝ์ฐ๋ H/W ๋ฑ๊ณผ ๋ฌด๊ดํ๊ฒ ์์ ์ ์ฝ๋๋ฅผ ํ ์คํธ๋ฅผ ํ๋ฉด์ ์์ฑํ๊ณ ์ถ์ ๊ฒ์ด๊ณ ,
2์ ๊ฒฝ์ฐ๋ ์๋ฒ ๋ก์ง๊ณผ ๋ฌด๊ดํ๊ฒ ์์ ์ ์ฝ๋๋ฅผ ํ ์คํธ๋ฅผ ํ๋ฉด์ ์์ฑํ๊ณ ์ถ์ ๊ฒ์ด๋ค.
๊ฐ๊ฐ์ ๋ํด์ ์ดํด๋ณด์.
- Humble ์ค๋ธ์ ํธ ํจํด์ ํ ์คํธ ๊ฐ๋ฅ์ฑ์ ๋์ด๊ธฐ ์ํด ํ ์คํธํ๊ธฐ ์ด๋ ค์ด ์์คํ ์ ๊ฒฝ๊ณ์ ์ ์ฉ
- ๊ฒฝ๊ณ(HW, DB ๋ฑ)์ ์ข ์๋ ํด๋์ค(Humble Object)์ ๋ก์ง์ ํ ์คํธ ํ ํ์ ์์ ์ ๋๋ก ์ต์ํ(humbleํ๊ฒ - Humble Controller)
- ๊ฒฝ๊ณ์ ์ข ์๋ ํด๋์ค(Humble Controller)์์ ์ถ์ถ๋ ์ค์ํ ๋น์ฆ๋์ค ๋ก์ง(Controller Logic)์ ๊ฒฝ๊ณ์ decouple๋๊ณ , ํ ์คํธ ๊ฐ๋ฅํ ํด๋์ค(Business Object)๋ก ์ด๋
- Business Object๋ Humbler Object๋ฅผ Boundary Interface๋ฅผ ํตํด์ ์ฌ์ฉํ๊ณ Humble Object์ ์กด์ฌ๋ฅผ ๋ชจ๋ฅด๊ฒ ๋๋ค(DIP)
- Humble Object๋ Boundary Interface๋ฅผ ๊ตฌํํ๋ค.
์ด ๋ง์ ์ฐ๋ฆฌ๊ฐ spring์ ์ฌ์ฉํ ๋ Controller, Dao, Repository ๋ฑ์ ๊ตฌํ์ฒด์์ ๊ฒฝ๊ณ(UI, DB)์ ์ํ ๋ก์ง๋ค์ ํ ์คํธํ ํ์๊ฐ ์์ ๋งํผ Humbleํ๊ฒ ํ์ฌ Interface ๋ค๋ก ์จ๊ธฐ๊ณ (Interface์ ๊ตฌํ์ฒด๊ฐ ๋๋๋ก), ์ฐ๋ฆฌ ์ฝ๋๋ ์ด Interface์ ์์กดํ๊ณ ํ ์คํธ ๊ฐ๋ฅํ๋๋ก ํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ํ ์คํธํ ํ์๊ฐ ์๋ ์ฝ๋๊ฐ ์๋ค๋ฉด ํ ์คํธํ๊ธฐ ์ด๋ ค์ด ์ฝ๋์ Interface๋ฅผ ํตํด ๋ถ๋ฆฌํ์ฌ ํ ์คํธ ๊ฐ๋ฅํ๋๋ก ํด์ผ ํ๋ค.
package humbleobject.milker;
public class HumbleMilkPumpController {
public void engage() {
for (int speed=1; speed<=6; speed++) {
setPumpSpeed(speed);
sleep(500);
}
setPumpSpeed(7);
}
/**
* hard to test code
* because too much dependent on control board
*
* turn speed into binary digits(3 digits)
* set speed in specific IO register
*/
private void setPumpSpeed(int speed) {
// set decimal to binary
// get IO register from control board
// set binary digits to IO register to control speed
}
private void sleep(int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) { }
}
}- ์ ์ถ๊ธฐ์์ ๊ฒ์ดํธ(์ ์๋ค์ด ์ ์ถ์ฅ์ ๊ฐ๋๋)๋ฅผ ์ ์ดํ๋ pump๊ฐ ์ปจํธ๋กค ๋ณด๋์ ์ํด ๊ตฌ๋๋๋ ๊ฒฝ์ฐ ๊ฐ์
- ์ปจํธ๋กค ๋ณด๋์ ํ์ ํ๋ pump ๊ด๋ จ ์ฝ๋(HumbleMilkPumpController#setPumpSpeed)๋ ํ ์คํธํ๊ธฐ ์ด๋ ต๋ค.
- HumbleMilkPumpController(์ปจํธ๋กค ๋ณด๋์ ํ์ ํ๋ ๋ก์ง)์์ ์ปจํธ๋กค ๋ณด๋์ ๋ถ๋ฆฌ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ์ถ์ถํ์ฌ ํ ์คํธ ๊ฐ๋ฅํ ํด๋์ค(MilkPump)๋ก ์ด๋์ํค๋ ๊ฒ
- ์ด ํ ์คํธ ๊ฐ๋ฅํ ํด๋์ค(MilkPump)๋ ์ปจํธ๋กค ๋ณด๋์ ๋ํด์ ์์ง ๋ชปํ๋ค. ์ด๋ฐ ์์ ํ์๋ ์ปจํธ๋กค๋ฌ์ ์ง์ ํต์ ํ๋ ์์ฃผ ์์ ์ฝ๋๋ง์ด ๋จ๊ณ , ํ ์คํธํ ํ์๊ฐ ์๊ฒ๋๋ค. HumbleController์ ๋จ์ ์ฝ๋๋ ํ ์คํธ๊ฐ ํ์์๋ ์ง์ ์ปจํธ๋กค๋ฌ๋ฅผ ์ ์ดํ๋ ์ต์ํ์ ์ฝ๋์ด๋ค.
์ ๋ค์ด์ด๊ทธ๋จ์์ ๊ฐ๋ฐ์์๊ฒ ์ค์ํ ์ฝ๋๋ Controller Logic์ด๋ค. ์ด ๋ก์ง์ด ์์กดํ๊ณ ์๋ Humble Controller๋ ํ ์คํธ, ๊ฐ๋ฐ์์ ์ ์ธํ๊ณ ์ถ๋ค.
- PumpRegister๋ ํ ์คํธํ๊ธฐ ์ด๋ ค์ด ์ฝ๋
- engage๊ฐ ํ ์คํธํ๋ ค๋ ์๊ณ ๋ฆฌ์ฆ
- setPumpSpeed, sleep๋ override ๊ฐ๋ฅ
- PumpRegister๊ฐ controll board๋ฅผ ์ ์ด(ํ ์คํธํ๊ธฐ ์ด๋ ค์ด IO ์์ )
์ด์ HumbleMilkPumpController๋ ๋ ์ด์ Humbleํ์ง ์์ผ๋ฏ๋ก MilkPump๋ก ์ด๋ฆ์ ๋ณ๊ฒฝํ๋ค.
ํ ์คํธํ๊ธฐ ์ด๋ ค์ด ์ฝ๋(PumpRegister)์ ์๊ณ ๋ฆฌ์ฆ(engage)์ ๋ค์๊ณผ ๊ฐ์ ์ ์ฐจ๋ก ๋ถ๋ฆฌํ๋ค.
- ํ ์คํธํ๊ธฐ ์ด๋ ค์ด ์ฝ๋(IO๋ฅผ ํ๋ ์ฝ๋์ฌ์)๋ฅผ ์ธํฐํ์ด์ค(PumpRegister) ๋ค๋ก ์จ๊ธด๋ค(ํ ์คํธํ๊ธฐ ์ด๋ ค์ด, ํ ํ์๊ฐ ์์๋งํผ Humbleํ ์ฝ๋๋ฅผ Humble Interface์ ๊ตฌํ์ฒด๊ฐ ๋๋๋กํ๋ค)
- ๋ชจ๋ rampUp ์๊ณ ๋ฆฌ์ฆ(engage() ๋ฉ์๋)์์ ์ฌ์ฉํ๋ ํจ์๋ค์ MilkPump ํด๋์ค ๋ด์ ํฌํผ ๋ฉ์๋๋ก ์ถ์ถํ๋ค(setPumpSpeed, sleep ๋ฑ์ protected๋ก ์ ์ธํด์ test์์ overrideํ ์ ์๋๋ก).
public class MilkPumpTest {
private String actions = "";
class TestingMilkPump extends MilkPump {
@Override
protected void setPumpSpeed(int speed) {
actions += speed + "ss";
}
@Override
protected void sleep(int milliseconds) {
actions += milliseconds + "s";
}
}
@Test
public void engage() {
TestingMilkPump milkPump = new TestingMilkPump();
milkPump.engage();
assertThat(actions, is("1ss500s2ss500s3ss500s4ss500s5ss500s6ss500s7ss"));
}
}์ด ํจํด์
- testable code์ boundary๋ฅผ ๋์ด์ untestableํ code๋ฅผ separateํ๊ณ decoupleํ์ฌ DI๋ฅผ ํตํด decoupling์ ์ด๋ฃฌ๋ค.
- ์ด๋ฅผ ํตํด untestable code๊ฐ testable code์ ์์กดํ๋๋ก DI๋ฅผ ์ ์ฉํ์ฌ ํ ์คํธ ๋ถ๊ฐํ ์ฝ๋๊ฐ ํ ์คํธ ๊ฐ๋ฅํ ์ฝ๋์ ์์กด์ฑ์ ๊ฐ๋๋กํ๋ค.
- ํ ์คํธํ๊ธฐ ์ด๋ ค์ด ์ด๋ ํ boundary์๋ ์ด ๋ฐฉ๋ฒ์ ์ ์ฉํ ์ ์๋ค.
-
H/W ๋ฑ ๊ตฌ์ฒด์ ์ธ ์ฝ๋์ ์์กดํ๋ ์ดํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์
- ๋ด ๋ก์ง์์ H/W ์์กด์ ์ธ ๋ถ๋ถ์ Humble Interface๋ฅผ ํตํด ๋ถ๋ฆฌํ๊ณ ๋ด ๋ก์ง์ Unit Test
-
์๋ฒ ๋ก์ง์ ์์กดํ๋ UI ๊ฐ๋ฐ์(App, Web Front)
- GUI์์ Process Interface(Humble Interface)๋ฅผ ๋ถ๋ฆฌํ๊ณ Fake ๊ตฌํ์ฒด๋ฅผ ์ถ๊ฐํ๊ณ
- ๋ด ๋ก์ง(GUI)์ ์๋์ผ๋ก ํ ์คํธํ ์ ์๋ ๋งํผ Humbleํ๊ฒ ์ ์ง



