์ด๋ฒ ์ฅ์์๋ ์ธ๋ถ์ API(๋ผ์ด๋ธ๋ฌ๋ฆฌ)๋ฅผ ์ฐ๋ฆฌ ์ฝ๋์ ๊น๋ํ๊ฒ ํตํฉํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํด์. ์ํํธ์จ์ด๊ฐ์ ๊ฒฝ๊ณ๋ฅผ ๊น๋ํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ธฐ๋ฒ๊ณผ ๊ธฐ๊ต๋ฅผ ์๋ ค์ค๋ค๊ณ ์๊ฐํ๋ฉด ๋์. ๋ํ์ ์ธ ์๋ก ๋ค๋ฅธ ํ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ์คํ ์์ค ํจํค์ง๋ฅผ ๋ค์ด๋ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ด์.
์ธํฐํ์ด์ค ์ ๊ณต์์ ์ฌ์ฉ์ ์ฌ์ด์๋ ํน์ ์ ๊ธด์ฅ์ด ์กด์ฌํด์. ์ธํฐํ์ด์ค ์ ๊ณต์๋ ์ต๋ํ ์ ์ฉ์ฑ์ ๋ํ ๋ค์ํ ํ๊ฒฝ์์ ์ฌ์ฉ๊ฐ๋ฅํ๊ฒ ๋ง๋ค๊ณ ์ถ์ดํด์. ํ์ง๋ง ์ฌ์ฉ์๋ ์ฌ์ฉ์์ ์๊ตฌ์ฌํญ์ ๋ง๋ ์ธํฐํ์ด์ค๋ฅผ ์ํด์. ๊ทธ๋์ ์ด๋ฌํ ๊ธด์ฅ์ผ๋ก ์์คํ ๊ฒฝ๊ณ์์ ๋ฌธ์ ๊ฐ ์๊ธธ ์์ง๊ฐ ๋ง์์.
Java์ Map ํจํค์ง๋ฅผ ์์๋ก ์ดํด๋ด์.
clear() void
containsKey(Object key) boolean
isEmpty() boolean
get(Object key) Object
Map์ ์์ ๊ฐ์ด ๋ค์ํ ๋ฉ์๋๋ฅผ ์ ๊ณตํด์. ๊ทธ๋ฐ๋ฐ ์ ํจํค์ง๋ฅผ ํ์ฉํด์ ์ด๋ค ๊ฐ๋ค์ ์ ์ฅ ๋ฐ ์กฐํํ ์ ์๊ฒ ๋ง๋ ๋ค๊ณ ํด๋ด์.
Map<String, Sensor> sensors = new HashMap<Sensor>();...Sensor s = Sensors.get(sensorId);์์ ๊ฐ์ด sensors์์ sensor๋ฅผ ๊ฐ์ ธ์ค๋ ์ฝ๋๋ฅผ ๋ง๋ค ์ ์์ด์. ๊ทธ๋ฐ๋ฐ Sensors์์ clear()๊ณผ ๊ฐ์ด ํ์ํ์ง ์์ ๊ธฐ๋ฅ์ ํจ๊ผ ๊ฐ์ง๊ณ ์์ด์. ๊ทธ๋์ ์ฝ๋ ์ฌ์ฉ์๊ฐ ์ค์ํ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ๊ณ ๋ง์ api์ ๋ํ ์ ๋ณด๋ฅผ ๋ฐ๊ฒ๋์. ๋ํ Map ํจํค์ง๊ฐ ์ ๋ฐ์ดํธ๋์ด ๋ฉ์๋ ๋ช ์ด ๋ฐ๊ปด๋ ์ง์ ์ ์ผ๋ก ์ฌ์ฉ์ ์ฝ๋์ ์ํฅ์ ์ค์. ๊ทธ๋์ ์ด๋ฐ ์ํฅ์ ์ต์ํํ๊ธฐ ์ํด ๊ฒฝ๊ณ๋ฅผ ์ ๋ถ๋ฆฌํด์ผํด์.
public class Sensors { private Map sensors = new HashMap(); public Sensor getById(String id) { return (Sensor) sensors.get(id); } ...}์ ์ฝ๋์ฒ๋ผ Sensors Class๋ก ๊ฒฝ๊ณ๋ฅผ ์ฒ๋ฆฌํด์ ๋ ธ์ถํ ์ธํฐํ์ด์ค๋ฅผ ์ ํํ๋ฉฐ ์ ๊ณตํ ์ ์์ด์. ๊ทธ๋์ ์ฌ์ฉํ๋ ์ฝ๋์์ ์ค๊ณ ๊ท์น๊ณผ ๋น์ฆ๋์ค ๊ท์น์ ๋ฐ๋ฅด๋๋ก ๊ฐ์ ํ์ฌ ์ค์ฉ์ ์ค์ผ ์ ์์ด์. ๋ํ Map์ด ์ ๋ฐ์ดํธ๋๋, Sensors ๋ด๋ถ ๊ตฌํ์์ ๋ณ๊ฒฝ์ฌํญ๋ง ์ ์ฉํด์ฃผ๋ฉด ๋์.
๋ฌผ๋ก Map์ ๋ง๋ ๋๋ง๋ค ์์๊ฐ์ด ์บก์ํํ๋ผ๋ ๊ฒ์ ์๋์์. Map๊ณผ ๊ฐ์ ์ ์ฌํ ๊ฒฝ๊ณ ์ธํฐํ์ด์ค๋ฅผ ์ฌ๊ธฐ์ ๊ธฐ ๋๊ธฐ์ง ๋ง๋ผ๋ ๊ฑฐ์์. Map ์ธ์คํด์ค๋ฅผ ์ธ์๋ก ๋๊ธฐ๊ฑฐ๋ ๋ฐํ ๊ฐ์ผ๋ก ์ฌ์ฉํ์ง ์๋๋ก ์ฃผ์ํด์ฃผ์ธ์.
์ธ๋ถ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ฅ ์ถ์์ ํ์ํ ์๊ฐ์ด ๋ ์ ์ด์ ธ์. ๊ทธ๋ฐ๋ฐ ์ธ๋ถ ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ์ฌ์ฉ๋ฒ์ ์์งํด์ผํด์.
ํด๋ฆฐ ์ฝ๋์์๋ ํ์ต ํ ์คํธ๋ผ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ฒฝ๊ณ๋ฅผ ์ดํผ๊ณ ์ตํ๊ธธ ๊ถ์ฅํด์. ํ์ต ํ ์คํธ๋ ๋จผ์ ๊ฐ๋จํ ํ ์คํธ ์ผ์ด์ค๋ฅผ ์์ฑํด ์ธ๋ถ ์ฝ๋๋ฅผ ์ตํ๋ ๋ฐฉ๋ฒ์ด์์. ํ์ต ํ ์คํธ๋ ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉํ๋ ค๋ ๋ฐฉ์๋๋ก ์ธ๋ถ API๋ฅผ ํ ์คํธ ์ฝ๋์์ ํธ์ถํ๋ ๊ฑฐ์์. ๊ทธ๋์ ํต์ ๋ ํ๊ฒฝ์์ API๋ฅผ ์ ๋๋ก ์ดํดํ๋์ง ํ์ธํด์.
public class LogTest { private Logger logger; @Before public void initialize() { logger = Logger.getLogger("logger"); logger.removeAllAppenders(); Logger.getRootLogger().removeAllAppenders(); } @Test public void basicLogger() { BasicConfigurator.configure(); logger.info("basicLogger"); } @Test public void addAppenderWithStream() { logger.addAppender(new ConsoleAppender( new PatternLayout("%p %t %m%n"), ConsoleAppender.SYSTEM_OUT)); logger.info("addAppenderWithStream"); } @Test public void addAppenderWithoutStream() { logger.addAppender(new ConsoleAppender( new PatternLayout("%p %t %m%n"))); logger.info("addAppenderWithoutStream"); }}์ ์ฝ๋๊ฐ ์๋ ์ log4j ์ตํ๊ธฐ๋ฅผ ์ํ ํ ์คํธ ์ฝ๋ ์์์์. ์ฝ์ ๋ก๊ฑฐ ์ด๊ธฐํํ๋ ๋ฐฉ๋ฒ์ ํ ์คํธ ์ฝ๋๋ก ์ตํ์ผ๋ ์ด์ ์ ๊ฒฝ๊ณ๋ฅผ ๋ ์์ ์ธ ๋ก๊ฑฐ ํด๋์ค๋ก ์บก์ํํ์ฌ ์ฌ์ฉํ๋ฉด ๋์. ์ด๋ฌ๋ฉด ์ฌ์ฉ์๋ log4j ๊ฒฝ๊ณ ์ธํฐํ์ด์ค๋ฅผ ๋ชฐ๋ผ๋ ๋ก๊ฑฐ๋ฅผ ์ฌ์ฉํ ์ ์์ด์. ๊ทธ๋ฆฌ๊ณ log4j๊ฐ ์ ๋ฐ์ดํธ๋์ด ์ ํ ์คํธ๊ฐ ์๋ฌ๋ฅผ ์ผ์ผํค๋ฉด, ๊ทธ๋ ์ ๋ฐ์ดํธ๋ ๋ถ๋ถ์ ๋ฐ์ํด์ฃผ๋ฉด๋๊ณ ์.
์ด๋ ๊ฒ ํ ์คํธ ์ผ์ด์ค๋ฅผ ํ์ฉํ๋ฉด ํจํค์ง์ ์๋ฒ์ ์ผ๋ก ์ด์ ๋ ์ฝ๊ณ , ์๋ก์ด ํจํค์ง๋ก ๋ฐ๊พธ๊ธฐ๋ ์ฌ์์ง๊ณ , ์ํ๋ ์ธํฐํ์ด์ค๋ก ๋ ธ์ถํ ์ ์์ด์.
์ผ์ ํ๋ค๋ณด๋ฉด, ์ด๋ค ์ด์ ๋ก๋ ๋ค๋ฅธ ํ์ API๊ฐ ์ ํด์ง์ง ์๋ ๊ฒฝ์ฐ๊ฐ ์์ด์. ๊ทธ๋์ ์๋ ์ฝ๋์ ๋ชจ๋ฅด๋ ์ฝ๋๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฒฝ๊ณ๊ฐ ์กด์ฌํ๊ฒ ๋๊ณ , ๊ฒฝ๊ณ ๋๋จธ๋ ๋ญ๊ฐ ์๋์ง ๋ณด์ด์ง๊ฐ ์์์. ํ์ง๋ง ์ด๋ค ๊ธฐ๋ฅ์ด ์ฐ๋ฆฌ ์ฝ๋์ ์ฌ์ฉ๋ ์ง๋ ๊ฐ์ผ๋ก๋ผ๋ ์ ์ ์์ด์. ๊ทธ๋์ ์ฐ๋ฆฌ ์ฝ๋์ ๋ค๋ฅธ ํ์ ์ฝ๋๊ฐ ๋ง๋๋ ๊ฒฝ๊ณ๋ฅผ ์ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋ง๋ค ์ ์์ด์.
์๋ฅผ ๋ค๋ฉด ์ฐ๋ฆฌ LocationService ์ฝ๋์ GPS ๋ชจ๋์ ๊ธฐ๋ฅ์ด ํ์ํ๋ค๊ณ ํด๋ด์. ๊ทธ๋ฐ๋ฐ GPS ๋ชจ๋์ ์ธํฐํ์ด์ค๊ฐ ์๋ค๊ณ ๊ฐ์ ํด์. ์ด๋ฐ ๊ฒฝ์ฐ์๋ GPS ๊ธฐ๋ฅ์ ๋ถ๋ฆฌํ๊ณ Adapter ํจํด์ ์ ์ฉํ์ฌ API๋ฅผ ์บก์ํํ์ฌ ๊ตฌํํ๋๋ก ๋ง๋ค๋ฉด ์ธ๋ถ GPS ๋ชจ๋ api๊ฐ ์ด๋ป๊ฒ ๋ฐ๋๋ ์ฝ๊ฒ ๋ฐ์ํ ์ ์์ด์.

์ Class Diagram UML์ด ๊ทธ ์์์์. ์์ ๊ฐ์ด ๊ตฌํํ๋ฉด ํ ์คํธ์ฝ๋๋ฅผ ๋ง๋ค๊ธฐ๋ ์ฌ์์. ExternalGpsClient๋ ์์ง๋ง FakeGpsGateway๋ฅผ ์ฌ์ฉํ์ฌ ์์๋ก ํ ์คํธํ ์ ์๊ธฐ ๋๋ฌธ์ด์์.
๊ฒฝ๊ณ์์๋ ๋ณ๊ฒฝ๊ณผ ๊ฐ์ ์ผ๋ค์ด ๋ง์ด ์ผ์ด๋์. ํ์ง๋ง ์ค๊ณ๊ฐ ์ ๋์ด ์๋ค๋ฉด ๋ณ๊ฒฝํ๋๋ฐ ๋ง์ ํฌ์์ ์์ ์ด ํ์ํ์ง ์์์.
๊ทธ๋์ ๊ฒฝ๊ณ์ ์์นํ๋ ์ฝ๋๋ ๊น๋ํ ๋ถ๋ฆฌํ๋๊ฒ ์ข์์. ๊ทธ๋ฆฌ๊ณ ๊ธฐ๋์น๋ฅผ ์ ์ํ๋ ํ ์คํธ ์ผ์ด์ค๋ฅผ ์์ฑํ๋ ๊ฒ๋ ์ข๊ณ ์. ์ฐ๋ฆฌ ์ฝ๋๋ ์ธ๋ถ ํจํค์ง์ ๋ํด์ ์์ธํ ์ ํ์๋ ์์ด์ผ ํด์. ์ด ๋ชฉํ๋ค์ ๋ฌ์ฑํ๊ธฐ ์ํด์๋ ์ธ๋ถ ํจํค์ง๋ฅผ ํธ์ถํ๋ ์ฝ๋๋ฅผ ๊ฐ๋ฅํ ์ค์ฌ ๊ฒฝ๊ณ๋ฅผ ๊ด๋ฆฌํด์ผํด์. Map ํจํค์ง ์ฌ์ฉ์ Wrapper Class๋ก ์ฒ๋ฆฌํ๊ฑฐ๋ ์ด๋ค ์ธํฐํ์ด์ค๋ก ์๋น์ค๋ฅผ ์ ๊ณตํ ์ง ๋ชจ๋ฅด๋ GPS ๋ชจ๋์ Adapter ํจํด์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ ์ฒ๋ผ ์ ๊ด๋ฆฌํด์ผํด์.
์์ง๋์ด๋ง์ ํต์ฌ์ ๋ถ๋ฆฌ๋ผ๋ ๊ฒ์ ์ ๋ณด์ฌ์ฃผ๋ ๊ฒ ๊ฐ์์. ๋ฌผ๋ก ๊ทธ ๋ถ๋ฆฌ์ ๋ชฉ์ ์ ํ์คํด์ผํ๊ฒ ์ง๋ง์. ์ด๊ฑธ ๋ณด๋ฉด์ ์ด๋ป๊ฒ ์ฝ๋๋ฅผ ๋ฆฌ๋ทฐํ๊ฑฐ๋ ํ๊ฐํ๋ ๊ฒ์ด ์ข์์ง ์ค์ค๋ก ๋ค์ ์๊ฐํด๋ณด๋ ๊ณ๊ธฐ๋ฅผ ๊ฐ์ก์ด์. ๊ฒฐ๋ก ์ ์ ์ฒด์ ์ธ ์ํคํ ์ฒ๋ฅผ ๋ณผ๋๋ ์ฝ๋๋ฅผ ๋ณผ๋ ์๊ฐ์ ๋ฌ๋ฆฌํด์ผํ๋ค๊ณ ์๊ฐํ๊ฒ๋์์ด์.
์๋ฅผ ๋ค๋ฉด ์ ์ฒด์ ์ธ ์๋น์ค ํ๋ฆ์ ์ํคํ ์ฒ ์ฒ๋ผ ํ๋ฆ์ ๋ด์ผํ๊ณ , ์ฝ๋๋ ๊ฒฝ๊ณ๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ทธ ์์ ์ฝ๋๋ง์ ๋ด์ผํ๋ค๊ณ ์๊ฐํ์ด์. ๊ฐ๋์ฉ ์ฝ๋๋ฅผ ๋ณด๋ค๋ณด๋ฉด ๊ฒฝ๊ณ ๋๋จธ๋ ํจ๊ป ๋ณด๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ, ๊ฒฝ๊ณ ๋๋จธ๊น์ง ๋ณด๋ฉด ๊ฐ๋ ์ด๋ ํ๋ฆ, ์ค์ํ ๊ฒ๋ค์ ๋ค ๋์น๊ณ ๋ค์ฃฝ๋ฐ์ฃฝ๋๋ ๊ฒ ๊ฐ์์. ๊ทธ๋ฆฌ๊ณ ์ ๊ทธ๋ ๊ฒ ๋ค์ฃฝ๋ฐ์ฃฝ ์ฝ๋๋ฅผ ์ ๋๋ก ํ๊ฐํ์ง ๋ชปํ๋์ง ๊นจ๋ฌ์ ๊ฒ ๊ฐ์์.
๊ฒฐ๋ก ์ ํด๋ฆฐ ์ฝ๋์๋ ์๊ด ์์ ์ ์์ง๋ง, ์ฝ๋๋ฅผ ๋ฆฌ๋ทฐํ ๋ ๊ฒฝ๊ณ ๋จ์๋ก ํ๊ฐํด์ผ ์ ๋๋ก ํ๊ฐํ ์ ์๊ณ , ์ฝ๋๋ฅผ ์ ๋๋ก ์ดํดํ๋ ๊ฒ์ด๋ผ ์๊ฐํ๋ค๋ ๊ฒ์ ๋๋ค.