์ฐ๋ฆฌ๋ ์์คํ ์ ๋ค์ด๊ฐ๋ ๋ชจ๋ ์ฝ๋๋ฅผ ๋ณดํต ์ง์ ๊ฐ๋ฐํ์ง ์๋๋ค. ์ธ๋ถ ํจํค์ง ๊ตฌ์ , ์คํ์์ค, ์ฌ๋ด ํ์ ์ ๊ณต ์ปดํฌ๋ํธ ์ฌ์ฉ ๋ฑ ๋ค์ํ ๋ฐฉ์์ผ๋ก ์ธ๋ถ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ค. ์ด ์ธ๋ถ ์ฝ๋๋ฅผ ์ฐ๋ฆฌ ์ฝ๋์ ๊น๋ํ๊ฒ ํตํฉํ๋ ๊ฒ์ ๊ฝค๋ ์ค์ํ๋ค. ์ด ๋ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฒ๊ณผ ๊ธฐ๊ต๋ฅผ ๋ฐฐ์๋ณด์.
์ธ๋ถ ์ฝ๋ ์ฌ์ฉํ๊ธฐ
์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ ์ ์ฅ๊ณผ ์ฌ์ฉํ๋ ์ ์ฅ ์ฌ์ด์๋ ํ์ฐ์ ์ธ ๊ธด์ฅ๊ฐ์ด ์กด์ฌํ๋ค. ์ ๊ณตํ๋ ์ ์ฅ์์๋ ๋ฒ์ฉ์ฑ์ ์ํด ๋ค์ํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ์ค๊ณํ๋ค. ๊ทธ์ ๋ฐ๋๋ก ์ฌ์ฉํ๋ ์ ์ฅ์์๋ ์ฌ์ฉํ ๋ ํธ๋ฆฌํ specificํ ์ธํฐํ์ด์ค๋ฅผ ์ํ๋ค. ์ด๊ฒ์ (์์คํ ) โ๊ฒฝ๊ณ์์์ ๊ธด์ฅโ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ๋ค์์ interface๋ฅผ ๋ณด์.
clear() void โ Map
containsKey(Object key) boolean โ Map
containsValue(Object value) boolean โ Map
clear() void โ Map
containsKey(Object key) boolean โ Map
containsValue(Object value) boolean โ Map
entrySet() Set โ Map
equals(Object o) boolean โ Map
get(Object key) Object โ Map
getClass() Class<? extends Object> โ Object
hashCode() int โ Map
isEmpty() boolean โ Map
keySet() Set โ Map
notify() void โ Object
notifyAll() void โ Object
put(Object key, Object value) Object โ Map
putAll(Map t) void โ Map
remove(Object key) Object โ Map
size() int โ Map
toString() String โ Object
values() Collection โ Map
wait() void โ Object
wait(long timeout) void โ Object
wait(long timeout, int nanos) void โ Object
์ด ์ํ์์ Sensor class๋ฅผ ์ ์ฅํ๋ Map ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค๊ณ ์๊ฐํด๋ณด์.
Map sensors = new HashMap();
Sensor s = (Sensor)sensors.get(sensorId);
์ด๋ ๊ฒ ์ฌ์ฉํ๋ ๋ฐฉ์์ด ์ฝ๋ ์ ๋ฐ์ ๊ฑธ์ณ์๋ค๊ณ ์๊ฐํด๋ณด์. ์ผ๋จ ๋ฌธ์ ๊ฐ ๋ญ๋๋ฉด, casting์ ๋ถ๋ด์ ์ง์ํ์ฌ ์๊ฒ๋๋ค๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ generic์ ์ฌ์ฉํ๋ฉด ๊ฐ๋ ์ฑ๊ณผ ์๋ ๋ชจ๋๋ฅผ ์ฑ๊ธธ ์ ์๋ค.
Map<String, Sensor> sensors = new HashMap<Sensor>();
Sensor s = sensors.get(sensorId);
์ด๋ฌ๋ฉด ๋์ผ๊น? ์๋๋ค. ๋ฌธ์ ๋ ์ฌ์ฉํ๋ ์ธก์์ ํ์์๋ method์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค. ์ด๋ฐ ์ฝ๋๊ฐ ์ด๊ณณ ์ ๊ณณ์์ ์ค๋ณต๋์ด ์ฌ์ฉ๋๋ค๋ฉด, Map์ interface๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ํด๋น ์ฝ๋๋ฅผ ๋ชจ๋ ์ฐพ์์ ๋ณ๊ฒฝ์์ผ์ฃผ์ด์ผ ํ๋ค. ์ฆ, ๋ณํ์ ๊ฐ๊ฑดํ์ง ๋ชปํ ๊ตฌ์กฐ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์, ์ข์ ํด๊ฒฐ๋ฐฉ๋ฒ์ wrapping์ด๋ค.
public class Sensors {
// ๊ฒฝ๊ณ์ ์ธํฐํ์ด์ค(์ด ๊ฒฝ์ฐ์๋ Map์ ๋ฉ์๋)๋ ์จ๊ฒจ์ง๋ค.
// Map์ ์ธํฐํ์ด์ค๊ฐ ๋ณ๊ฒฝ๋๋๋ผ๋ ์ฌํ๋ฅผ ์ต์ํํ ์ ์๋ค. ์๋ฅผ ๋ค์ด Generic์ ์ฌ์ฉํ๋ ์ง์ ์บ์คํ
ํ๋ ๊ทธ๊ฑด ๊ตฌํ ๋ํ
์ผ์ด๋ฉฐ Sensorํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ์ธก์์๋ ์ ๊ฒฝ์ธ ํ์๊ฐ ์๋ค.
// ์ด๋ ๋ํ ์ฌ์ฉ์์ ๋ชฉ์ ์ ๋ฑ ๋ง๊ฒ ๋์์ธ๋์ด ์์ผ๋ฏ๋ก ์ดํดํ๊ธฐ ์ฝ๊ณ ์๋ชป ์ฌ์ฉํ๊ธฐ ์ด๋ ต๊ฒ ๋๋ค.
private Map sensors = new HashMap();
public Sensor getById(String id) {
return (Sensor)sensors.get(id);
}
}
๋ชจ๋ Map์ ์ด๋ฐ์์ผ๋ก ๋์์ธํ๋ผ๋ ๊ฒ์ ์๋๋ค. ํ์ง๋ง, โ๊ฒฝ๊ณ์ ์๋ ์ธํฐํ์ด์คโ์ ๊ฒฝ์ฐ ์์คํ ์ ๋ฐ์์ ์ฌ์ฉํ๋ ๊ฒ์ ์ข์ง ์๋ค. ๋ค์๊ณผ ๊ฐ์ ์์น์ ์งํค๋ ๊ฒ์ด ์ข๋ค.
- ํด๋น ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ class ๋ด๋ถ์ ๋ฃ๋๋ค.
- ํน์ ๊ฐ๊น์ด ๊ณ์ด์ class์ ๋ฃ๋๋ค.
- Map์ธ์คํด์ค๋ฅผ ๊ณต๊ฐ API์ ์ธ์๋ก ๋๊ธฐ๊ฑฐ๋ ๋ฐํํ์ง ์๋๋ค.
์ฆ, ๋ด๋ถ์์๋ง ์ฌ์ฉํ๋ผ๋ ๋ง์ด๋ค.
๊ฒฝ๊ณ ์ดํผ๊ณ ์ตํ๊ธฐ
third party ์ฝ๋๋ฅผ ์ฌ์ฉํ ๋, ์ฃผ์ํด์ผ ํ๋ ์ ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋, ์ด๊ฒ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฌธ์ ์ธ์ง, ์ฐ๋ฆฌ ์ฝ๋ ๋ฌธ์ ์ธ์ง ํ์ ์ด ์ฌ์์ผ ํ๋ค๋ ์ ์ด๋ค. ๋ถ๋ช ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ณณ์ด ์ฐ๋ฆฌ์ฑ ์์ด ์๋๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฑ ์์ธ๋ฐ ๋๋ฒ๊น ์ ์๊ฐ์ ์ค๋ ์๋๋ค๋ฉด ์ด๋ ๋ถ๋ช ํ ๋ฆฌ์์ค ๋ญ๋น์ผ ๊ฒ์ด๋ค.
์ด๋ฌํ ์ ์ ์ฐฉ์ํ์ฌ ์ฐ๋ฆฌ๋ ์ ์ด๋ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ์ฝ๋์ ๋ํด์๋ ํ ์คํธ๋ฅผ ํ ํ์๊ฐ ์๋ค. ์ด๊ฒ ์ฅ๊ธฐ์ ์ผ๋ก ๋ ์ ์ ๋ฆฌ์์ค๋ฅผ ๋ค์ด๋ ์ผ์ผ ์ ์๋ค. ๋ฐ๋ก ๋ฌธ์ ์ ์ ์ฐพ์ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ฅผ ์ง ๋ด์ปคํฌ๋ โํ ์คํธ ๊ณต๋ถํ๊ธฐโ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
log4j ์ตํ๊ธฐ
๊ทธ๋ผ ์ค์ ๋ก ์ด๋ค ๋ฐฉ์์ผ๋ก ์ตํ๋์ง ์์๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋ค.
// 1.
// ์ฐ์ log4j ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค์ด๋ฐ์.
// ๊ณ ๋ฏผ ๋ง์ด ํ์ง ๋ง๊ณ ๋ณธ๋ฅ์ ๋ฐ๋ผ "hello"๊ฐ ์ถ๋ ฅ๋๊ธธ ๋ฐ๋ผ๋ฉด์ ์๋์ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์.
@Test
public void testLogCreate() {
Logger logger = Logger.getLogger("MyLogger");
logger.info("hello");
}
// 2.
// ์ ํ
์คํธ๋ "Appender๋ผ๋๊ฒ ํ์ํ๋ค"๋ ์๋ฌ๋ฅผ ๋ฑ๋๋ค.
// ์กฐ๊ธ ๋ ์ฝ์ด๋ณด๋ ConsoleAppender๋ผ๋๊ฒ ์๋๊ฑธ ์์๋๋ค.
// ๊ทธ๋์ ConsoleAppender๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ฃ์ด์ค๋ดค๋ค.
@Test
public void testLogAddAppender() {
Logger logger = Logger.getLogger("MyLogger");
ConsoleAppender appender = new ConsoleAppender(); // ์ฌ๊ธฐ
logger.addAppender(appender); // ์ฌ๊ธฐ
logger.info("hello");
}
// 3.
// ์์ ๊ฐ์ด ํ๋ฉด "Appender์ ์ถ๋ ฅ ์คํธ๋ฆผ์ด ์๋ค"๊ณ ํ๋ค.
// ์ด์ํ๋ค. ๊ฐ์ง๊ณ ์๋๊ฒ ์ด์ฑ์ ์ผ๊ฒ ๊ฐ์๋ฐ...
// ๊ตฌ๊ธ์ ๋์์ ๋น๋ ค, ๋ค์๊ณผ ๊ฐ์ด ํด๋ณด์๋ค.
@Test
public void testLogAddAppender() {
Logger logger = Logger.getLogger("MyLogger");
logger.removeAllAppenders();
logger.addAppender(new ConsoleAppender(
new PatternLayout("%p %t %m%n"),
ConsoleAppender.SYSTEM_OUT));
logger.info("hello");
}
// ์ฑ๊ณตํ๋ค. ํ์ง๋ง ConsoleAppender๋ฅผ ๋ง๋ค์ด๋๊ณ ConsoleAppender.SYSTEM_OUT์ ๋ฐ๋๊ฑด ์ด์ํ๋ค.
// ๊ทธ๋์ ๋นผ๋ดค๋๋ ์ ๋์๊ฐ๋ค.
// ํ์ง๋ง PatternLayout์ ์ ๊ฑฐํ๋ ๋์๊ฐ์ง ์๋๋ค.
// ๊ทธ๋์ ๋ฌธ์๋ฅผ ์ดํด๋ดค๋๋ "ConsoleAppender์ ๊ธฐ๋ณธ ์์ฑ์๋ unconfigured์ํ"๋๋ค.
// ๋ช
๋ฐฑํ์ง๋ ์๊ณ ์ค์ฉ์ ์ด์ง๋ ์๋ค... ๋ฒ๊ทธ์ด๊ฑฐ๋, ์ ์ด๋ "์ผ๊ด์ ์ด์ง ์๋ค"๊ณ ๋๊ปด์ง๋ค.
// ์กฐ๊ธ ๋ ๊ตฌ๊ธ๋ง, ๋ฌธ์ ์ฝ๊ธฐ, ํ
์คํธ๋ฅผ ๊ฑฐ์ณ log4j์ ๋์๋ฒ์ ์์๋๊ณ ๊ทธ๊ฒ์ ๊ฐ๋จํ ์ ๋ํ
์คํธ๋ก ๊ธฐ๋กํ๋ค.
// ์ด์ ์ด ์ง์์ ๊ธฐ๋ฐ์ผ๋ก log4j๋ฅผ ๋ํํ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ ์๋ค.
// ๋๋จธ์ง ์ฝ๋์์๋ log4j์ ๋์์๋ฆฌ์ ๋ํด ์ ํ์๊ฐ ์๊ฒ ๋๋ค.
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");
}
}
ํ์ต ํ ์คํธ(Learning Test)๋ ๊ณต์ง ์ด์์ด๋ค
์ด๋ฐ ๋ฐฉ์์ผ๋ก, ๋จผ์ ํ ์คํธ ์ฝ๋์์ ์์ฑํ๋ฉด์ ์ตํ๋ ๋ฐฉ์์ ๊ต์ฅํ ํจ์จ์ ์ด๋ค.
- ํ์ํ ์ง์๋ง ํ๋ณดํ๋ ๋ฐฉ๋ฒ์ด๋ค.
- ์ดํด๋๋ฅผ ๋ํ์ฃผ๋ ์คํ์ ์ธ ๋ฐฉ์์ด๋ค.
- ๋๋ ๋น์ฉ์ด ์๋ค. ๊ทธ๋ฅ ํด๋ณด๋ฉด ๋๋ค.
- ๋ฉ์ธ ๋ก์ง์ ์ํฅ์ ์ฃผ์ง ์์ผ๋ฉด์ ์ดํด๋ ํ ์ ์๋ค.
- third party ์ฝ๋๊ฐ ๋ฐ๋๋ฉด ํ์ต ํ ์คํธ๋ฅผ ํตํด โํ์ํ ๊ธฐ๋ฅโ์ด ์ ๋์ํ๋์ง ํ์ธํ ์ ์๋ค.
์ด๋ฌํ ์ด์ ์ธ์๋, ์ด๋ฌํ ๊ฒฝ๊ณ ๋ถ๊ทผ์์์ test๋ ์ ๋ฒ์ ์ผ๋ก ์ด์ ์ ์์ด ๋ณด๋ค ๋น ๋ฅธ ์ ํ์ ๊ฐ๋ฅ์ผํ๋ค.
์์ง ์กด์ฌํ์ง ์๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ธฐ
์์ง ๊ฐ๋ฐ๋์ง ์์ ๋ชจ๋์ด ์๋ค๊ณ ํ์. ๊ธฐ๋ฅ์ ์ปค๋ ์ธํฐํ์ด์ค๋ ์๋ค. ํด๋น ๋ชจ๋์ ์์กด์ ์ธ ๊ธฐ๋ฅ์ด ์๋ค๋ฉด ์ด๋ฌํ ์ํฉ์ ๊ต์ฅํ ์ฑ๊ฐ์๋ค. ๊ทธ๋ ๋ค๊ณ ํด์ ๊ตฌํ์ด ๋ฆ์ด์ง๋ ๊ฒ์ ์ํ์ง๋ ์๋๋ค.
์ ์์ ์์๋ก ๋ฌด์ ํต์ ์์คํ ์ ๊ตฌ์ถํ๋ ํ๋ก์ ํธ๋ฅผ ๋ค์ด๋ณด๊ฒ ๋ค. ํ ์์ ํ๋ถ ํ์ผ๋ก โ์ก์ ๊ธฐโ๋ฅผ ๋ด๋นํ๋ ํ์ด ์์๋๋ฐ ๋๋จธ์ง ํ์๋ค์ ์ก์ ๊ธฐ์ ๋ํ ์ง์์ด ๊ฑฐ์ ์์๋ค. โ์ก์ ๊ธฐโํ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ์ง ์์๋ค. ํ์ง๋ง ์ ์๋ โ์ก์ ๊ธฐโํ์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ โ์ํ๋โ ๊ธฐ๋ฅ์ ์ ์ํ๊ณ ์ธํฐํ์ด์ค๋ก ๋ง๋ค์๋ค. [์ง์ ํ ์ฃผํ์๋ฅผ ์ด์ฉํด ์ด ์คํธ๋ฆผ์์ ๋ค์ด์ค๋ ์๋ฃ๋ฅผ ์๋ ๋ก๊ทธ ์ ํธ๋ก ์ ์กํ๋ผ] ์ด๋ ๊ฒ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํจ์ผ๋ก์จ ๋ฉ์ธ ๋ก์ง์ ๋ ๊น๋ํ๊ฒ ์งค ์ ์์๊ณ ๋ชฉํ๋ฅผ ๋ช ํํ๊ฒ ๋ํ๋ผ ์ ์์๋ค. ์ด๋ Adapter Pattern์ด๋ค.
public class FakeTransmitter implements Transimitter {
public void transmit(SomeType frequency, OtherType stream) {
// ์ค์ ๊ตฌํ์ด ๋๊ธฐ ์ ๊น์ง ๋๋ฏธ ๋ก์ง์ผ๋ก ๋์ฒด
}
}
public class CommunicationController {
// Transmitterํ์ API๊ฐ ์ ๊ณต๋๊ธฐ ์ ์๋ ์๋์ ๊ฐ์ด ์ฌ์ฉํ๋ค.
public void someMethod() {
Transmitter transmitter = new FakeTransmitter();
transmitter.transmit(someFrequency, someStream);
}
}
public interface Transimitter {
public void transmit(SomeType frequency, OtherType stream);
}
// ๊ฒฝ๊ณ ๋ฐ์ API
public class RealTransimitter {
// ์บก์ํ๋ ๊ตฌํ
...
}
public class TransmitterAdapter extends RealTransimitter implements Transimitter { // Transimitter ์ธํฐํ์ด์ค ๋ฌด์กฐ๊ฑด ๊ตฌํ
public void transmit(SomeType frequency, OtherType stream) {
// RealTransimitter(์ธ๋ถ API)๋ฅผ ์ฌ์ฉํด ์ค์ ๋ก์ง์ ์ฌ๊ธฐ์ ๊ตฌํ.
// Transmitter์ ๋ณ๊ฒฝ์ด ๋ฏธ์น๋ ์ํฅ์ ์ด ๋ถ๋ถ์ ํ์ ๋๋ค.
}
}
public class CommunicationController {
// Transmitterํ์ API๊ฐ ์ ๊ณต๋๋ฉด ์๋์ ๊ฐ์ด ์ฌ์ฉํ๋ค.
public void someMethod() {
Transmitter transmitter = new TransmitterAdapter();
transmitter.transmit(someFrequency, someStream);
}
}
๊นจ๋ํ ๊ฒฝ๊ณ
์ข์ ์ํํธ์จ์ด ๋์์ธ์ ๋ณ๊ฒฝ์ด ์๊ธธ ๊ฒฝ์ฐ ๋ง์ ์ฌ์์ ์์ด ๋ณ๊ฒฝ์ ๋ฐ์ํ ์ ์์ด์ผ ํ๋ค. ์์์ ์์๋ณธ ๋ด์ฉ๋ค์ ์ ๋ฆฌํด๋ณด์.
- ๊ฒฝ๊ณ์์ ๋ง์ด ๋ฐ์ํ๋ โ๋ณ๊ฒฝโ์ ๋์ฒํ ์ ์๋๋ก ์ฃผ์ํด์ผ ํ๋ค.
- ์ด ๋ณ๊ฒฝ์ ๋์ฒํ๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ๊ฒฝ๊ณ์ ์์นํ ์ฝ๋๋ฅผ ๊น๋ํ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์๋ค.
- ์ธ๋ถ ํจํค์ง์ ๋ํด ์ธ์ธํ๊ฒ ์ ํ์๊ฐ ์๋ค.
- ์ด๋ฅผ wrappingํ๋ ๋ฐฉ๋ฒ์ ํตํด ๋ณ๊ฒฝ ๋ฒ์๋ฅผ ์ ์ฝํ ์ ์๋ค.
- ํต์ ๋ถ๊ฐ๋ฅํ ์ธ๋ถ ํจํค์ง ์์กด๋ณด๋ค ํต์ ๊ฐ๋ฅํ ์ฐ๋ฆฌ ์ฝ๋์ ์์กดํ๋ ๊ฒ์ด ์ข๋ค.
- ํน์ Adapter ํจํด์ ์ฌ์ฉํ์ฌ ๋ด๊ฐ ์ํ๋ ์ธํฐํ์ด์ค๋ก ์ ๊ณตํ ์ ์๋๋ก ํ์.