์๋
ํ์ธ์! ์ค๋ ์ฐ๋ฆฌ๋ ๊ณ์ํด์ ๋์์ธ ํจํด์ ์ฐ๊ตฌํ๊ณ ์ถ์ ํฉํ ๋ฆฌ ์ ๋ํด ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค . ๊ฐ์ ์ค์ ์ฐ๋ฆฌ๊ฐ ํ ์ผ:
- ์ถ์ ํฉํ ๋ฆฌ๊ฐ ๋ฌด์์ธ์ง, ์ด ํจํด์ด ํด๊ฒฐํ๋ ๋ฌธ์ ๋ ๋ฌด์์ธ์ง ๋ ผ์ํด ๋ณด๊ฒ ์ต๋๋ค.
- ์ฐ๋ฆฌ๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ปคํผ๋ฅผ ์ฃผ๋ฌธํ๊ธฐ ์ํ ํฌ๋ก์ค ํ๋ซํผ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋ ์์ํฌ๋ฅผ ๋ง๋ค ๊ฒ์ ๋๋ค.
- ๋ค์ด์ด๊ทธ๋จ๊ณผ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ด ํจํด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
- ๋ณด๋์ค๋ก ๊ฐ์์๋ ์ด์คํฐ ์๊ทธ๊ฐ ์จ๊ฒจ์ ธ ์์ต๋๋ค. ๋๋ถ์ Java๋ฅผ ์ฌ์ฉํ์ฌ ์ด์ ์ฒด์ ์ ์ด๋ฆ์ ๊ฒฐ์ ํ๊ณ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ํ๋ ๋๋ ๋ค๋ฅธ ์์ ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ธ ์ ์์ต๋๋ค.
- Java์ ์์;
- Java์ ์ถ์ ํด๋์ค ๋ฐ ๋ฉ์๋.
์ถ์ ํฉํ ๋ฆฌ ํจํด์ ์ด๋ค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๊น?
๋ชจ๋ ํฉํ ๋ฆฌ ํจํด๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ถ์ ํฉํ ๋ฆฌ๋ ์๋ก์ด ๊ฐ์ฒด ์์ฑ์ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ๊ทธ๊ฒ์ ๋์์ผ๋ก ์ฐ๋ฆฌ๋ ์ํธ ์ฐ๊ฒฐ๋ ๊ฐ์ฒด์ ๋ค์ํ ๊ณ์ด์ "๋ฆด๋ฆฌ์ค"๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ์ํธ ์ฐ๊ด๋ ๊ฐ์ฒด์ ๋ค์ํ ๊ณ์ด...์ด๊ฒ ๋ฌด์์ธ๊ฐ์? ๊ฑฑ์ ํ์ง ๋ง์ญ์์ค. ์ค์ ๋ก๋ ๋ชจ๋ ๊ฒ์ด ์๊ฐ๋ณด๋ค ๊ฐ๋จํฉ๋๋ค. ๊ด๋ จ ๊ฐ์ฒด์ ๊ณ์ด์ด ๋ฌด์์ธ์ง๋ถํฐ ์์ํด ๋ณด๊ฒ ์ต๋๋ค. ๋น์ ๊ณผ ๋ด๊ฐ ์ ๋ต์ ๊ฐ๋ฐํ๊ณ ์๊ณ ๊ทธ ์์ ์ฌ๋ฌ ์ ํฌ ์ ๋์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.- ๋ณด๋ณ;
- ๊ธฐ๋ณ๋;
- ๊ถ์.
์ฐ๋ฆฌ๋ ๊ณ์ํด์ ์ปคํผ์์ ์๋ํํ๊ณ ์์ต๋๋ค
์ง๋ ๊ฐ์ ์์ ์ฐ๋ฆฌ๋ ํฉํ ๋ฆฌ ๋ฐฉ์ ํจํด์ ์ฐ๊ตฌํ๊ณ , ์ด๋ฅผ ํตํด ์ปคํผ ์ฌ์ ์ ํ์ฅํ๊ณ ์ฌ๋ฌ ๊ฐ์ ์๋ก์ด ์ปคํผ ํ๋งค ์ง์ ์ ์ด ์ ์์์ต๋๋ค. ์ค๋๋ ์ฐ๋ฆฌ๋ ์ฌ์ ์ ํ๋ํํ๊ธฐ ์ํ ๋ ธ๋ ฅ์ ๊ณ์ํ ๊ฒ์ ๋๋ค. ์ถ์ ํฉํ ๋ฆฌ ํจํด์ ์ฌ์ฉํ์ฌ ์จ๋ผ์ธ์ผ๋ก ์ปคํผ๋ฅผ ์ฃผ๋ฌธํ๊ธฐ ์ํ ์๋ก์ด ๋ฐ์คํฌํฑ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋ฐ์ ๋ง๋ จํ ๊ฒ์ ๋๋ค. ๋ฐ์คํฌํ์ฉ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ ๋ ํญ์ ํฌ๋ก์ค ํ๋ซํผ์ ๋ํด ์๊ฐํด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ ์ macOS์ Windows ๋ชจ๋์์ ์๋ํด์ผ ํฉ๋๋ค(์คํฌ์ผ๋ฌ: Linux๋ ์์ ๋ก ๋จ๊ฒจ๋๊ฒ ์ต๋๋ค). ์ฐ๋ฆฌ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ๋ชจ์ต์ผ๊น์? ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ์ด๋ ํ ์คํธ ํ๋, ์ ํ ํ๋ ๋ฐ ๋ฒํผ์ผ๋ก ๊ตฌ์ฑ๋ ์์์ ๋๋ค. ๋ค๋ฅธ ์ด์ ์ฒด์ ๋ฅผ ์ฌ์ฉํด ๋ณธ ๊ฒฝํ์ด ์๋ค๋ฉด Windows์ ๋ฒํผ์ด Mac๊ณผ ๋ค๋ฅด๊ฒ ๋ ๋๋ง๋๋ค๋ ์ ์ ํ์คํ ์ ์ ์์ ๊ฒ์ ๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก... ์, ์์ํ๊ฒ ์ต๋๋ค. ์ด๋ฏธ ์ดํดํ์ จ๊ฒ ์ง๋ง ์ ํ๊ตฐ์ ์ญํ ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ทธ๋ํฝ ์ธํฐํ์ด์ค ์์๊ฐ ์์ต๋๋ค.- ๋ฒํผ;
- ํ ์คํธ ํ๋;
- ์ ํ ํ๋์ ๋๋ค.
onClick
, onValueChanged
๋๋ ์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ ์ํ ์ ์์ต๋๋ค onInputChanged
. ์ ๊ฒ๋ค. ๋ค์ํ ์ด๋ฒคํธ(๋ฒํผ ํด๋ฆญ, ํ
์คํธ ์
๋ ฅ, ์ ํ ์์์์ ๊ฐ ์ ํ)๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ๋ฉ์๋์
๋๋ค. ์ด ๋ชจ๋ ๊ฒ์ ์์ ์ ๊ณผ๋ถํ๊ฐ ๊ฑธ๋ฆฌ์ง ์๋๋ก ํ๊ณ ํฉํ ๋ฆฌ ํจํด์ ์ฐ๊ตฌํ๋ ๋ฐ ๋ ์๊ฐ์ ์ผ๋ก ๋ง๋ค๊ธฐ ์ํด ์๋์ ์ผ๋ก ์๋ต๋์์ต๋๋ค. ์ ํ์ ๋ํ ์ถ์ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํด ๋ณด๊ฒ ์ต๋๋ค.
public interface Button {}
public interface Select {}
public interface TextField {}
๊ฐ ์ด์ ์ฒด์ ์ ๋ํด ํด๋น ์ด์ ์ฒด์ ์คํ์ผ๋ก ์ธํฐํ์ด์ค ์์๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ๋ Windows์ MacOS์ฉ์ผ๋ก ๊ธ์ ์๋๋ค. Windows์ฉ ๊ตฌํ์ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
public class WindowsButton implements Button {
}
public class WindowsSelect implements Select {
}
public class WindowsTextField implements TextField {
}
์ด์ MacOS์์๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค.
public class MacButton implements Button {
}
public class MacSelect implements Select {
}
public class MacTextField implements TextField {
}
์์ฒญ๋. ์ด์ ๊ธฐ์กด์ ๋ชจ๋ ์ถ์ ์ ํ ์ ํ์ ์์ฑํ๋ ์ถ์ ํฉํ ๋ฆฌ๋ฅผ ์์ํ ์ ์์ต๋๋ค.
public interface GUIFactory {
Button createButton();
TextField createTextField();
Select createSelect();
}
์๋ฒฝํ. ๋ณด์๋ค์ํผ ์ง๊ธ๊น์ง ๋ณต์กํ ๊ฒ์ ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ชจ๋ ๊ฒ์ด ๊ฐ๋จํฉ๋๋ค. ์ ํ๊ณผ ์ ์ฌํ๊ฒ ์ฐ๋ฆฌ๋ ๊ฐ OS์ ๋ํด ๊ณต์ฅ์ ๋ค๋ฅด๊ฒ ๊ตฌํํฉ๋๋ค. Windows๋ถํฐ ์์ํด ๋ณด๊ฒ ์ต๋๋ค.
public class WindowsGUIFactory implements GUIFactory {
public WindowsGUIFactory() {
System.out.println("Creating gui factory for Windows OS");
}
public Button createButton() {
System.out.println("Creating Button for Windows OS");
return new WindowsButton();
}
public TextField createTextField() {
System.out.println("Creating TextField for Windows OS");
return new WindowsTextField();
}
public Select createSelect() {
System.out.println("Creating Select for Windows OS");
return new WindowsSelect();
}
}
์๋ ๋ฐฉ์์ ์์ธํ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ๋ฉ์๋ ๋ฐ ์์ฑ์ ๋ด๋ถ์ ์ฝ์ ์ถ๋ ฅ์ด ์ถ๊ฐ๋์์ต๋๋ค. ์ด์ macOS์ ๊ฒฝ์ฐ:
public class MacGUIFactory implements GUIFactory {
public MacGUIFactory() {
System.out.println("Creating gui factory for macOS");
}
@Override
public Button createButton() {
System.out.println("Creating Button for macOS");
return new MacButton();
}
@Override
public TextField createTextField() {
System.out.println("Creating TextField for macOS");
return new MacTextField();
}
@Override
public Select createSelect() {
System.out.println("Creating Select for macOS");
return new MacSelect();
}
}
์ฐธ๊ณ : ๊ฐ ๋ฉ์๋๋ ์๋ช
์ ๋ฐ๋ผ ์ถ์ ์ ํ์ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ฉ์๋ ๋ด์์ ์ฐ๋ฆฌ๋ ์ ํ์ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ์ ์์ฑํฉ๋๋ค. ์ด๋ ํน์ ์ธ์คํด์ค ์์ฑ์ ์ ์ดํ๋ โโ์ ์ผํ ์ฅ์์
๋๋ค. ์ด์ ์์ ํด๋์ค๋ฅผ ์์ฑํ ์ฐจ๋ก์
๋๋ค. ์ด๋ ํ๋๊ฐ ์ธํฐํ์ด์ค ์์์ธ Java ํด๋์ค์
๋๋ค.
public class OrderCoffeeForm {
private final TextField customerNameTextField;
private final Select coffeTypeSelect;
private final Button orderButton;
public OrderCoffeeForm(GUIFactory factory) {
System.out.println("Creating order coffee form");
customerNameTextField = factory.createTextField();
coffeTypeSelect = factory.createSelect();
orderButton = factory.createButton();
}
}
์ถ์ ํฉํ ๋ฆฌ๋ ์ธํฐํ์ด์ค ์์๋ฅผ ์์ฑํ๋ ์์ ์์ฑ์์ ์ ๋ฌ๋ฉ๋๋ค. ํน์ OS์ ๋ํ ์ธํฐํ์ด์ค ์์๋ฅผ ์์ฑํ ์ ์๋๋ก ํ์ํ ํฉํ ๋ฆฌ ๊ตฌํ์ ์์ฑ์์ ์ ๋ฌํฉ๋๋ค.
public class Application {
private OrderCoffeeForm orderCoffeeForm;
public void drawOrderCoffeeForm() {
// ะะฟัะตะดะตะปะธะผ Name ะพะฟะตัะฐัะธะพะฝะฝะพะน ัะธััะตะผั, ะฟะพะปััะธะฒ meaning ัะธััะตะผะฝะพะน ะฟัะพะฟะตััะธ ัะตัะตะท System.getProperty
String osName = System.getProperty("os.name").toLowerCase();
GUIFactory guiFactory;
if (osName.startsWith("win")) { // ะะปั windows
guiFactory = new WindowsGUIFactory();
} else if (osName.startsWith("mac")) { // ะะปั mac
guiFactory = new MacGUIFactory();
} else {
System.out.println("Unknown OS, can't draw form :( ");
return;
}
orderCoffeeForm = new OrderCoffeeForm(guiFactory);
}
public static void main(String[] args) {
Application application = new Application();
application.drawOrderCoffeeForm();
}
}
Windows์์ ์ ํ๋ฆฌ์ผ์ด์
์ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ถ๋ ฅ์ด ํ์๋ฉ๋๋ค.
Creating gui factory for Windows OS
Creating order coffee form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
Mac์์๋ ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค.
Creating gui factory for macOS
Creating order coffee form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
๋ฆฌ๋
์ค์ ๊ฒฝ์ฐ:
Unknown OS, can't draw form :(
๊ธ์, ๋น์ ๊ณผ ๋๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๋ก ์ ๋ด๋ฆฝ๋๋ค. ์ฐ๋ฆฌ๋ ํน์ OS์ ์ ํฉํ ์ธํฐํ์ด์ค ์์๋ฅผ ์ ํํ๊ฒ ์์ฑํ๋ GUI ์ ํ๋ฆฌ์ผ์ด์
์ฉ ํ๋ ์์ํฌ๋ฅผ ์์ฑํ์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ๋ง๋ ๊ฒ์ ๊ฐ๋จํ ๋ฐ๋ณตํด ๋ณด๊ฒ ์ต๋๋ค.
- ์ ํ๊ตฐ: ์ ๋ ฅ ํ๋, ์ ํ ํ๋ ๋ฐ ๋ฒํผ.
- Windows ๋ฐ macOS์ฉ์ผ๋ก ์ด ์ ํ๊ตฐ์ ๋ค์ํ๊ฒ ๊ตฌํํฉ๋๋ค.
- ์ ํ ์์ฑ์ ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ ์ถ์ ํฉํ ๋ฆฌ์ ๋๋ค.
- ์ฐ๋ฆฌ ๊ณต์ฅ์ ๋ ๊ฐ์ง ๊ตฌํ์ ๊ฐ๊ฐ ํน์ ์ ํ๊ตฐ์ ๋ง๋๋ ์ผ์ ๋ด๋นํฉ๋๋ค.
- ์ถ์ ํฉํ ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ๊ฐ์ผ๋ก ์์ฑ์์์ ์ด๊ธฐํ๋๋ ์ถ์ ์ธํฐํ์ด์ค ์์๋ฅผ ํ๋๋ก ํฌํจํ๋ Java ํด๋์ค์ธ ์์์ ๋๋ค.
- ์์ฉ ์์ . ๊ทธ ์์๋ ๊ณต์ฅ์ ํ์ ๊ตฌํ์ ์์ฑ์์ ์ ๋ฌํ๋ ์์์ ๋ง๋ญ๋๋ค.
์ถ์ ํฉํ ๋ฆฌ: ์ฌ์ฉ ์ง์นจ
Abstract Factory๋ ํน์ ์ ํ ํด๋์ค์ ์ฝ๋งค์ด์ง ์๊ณ ๋ค์ํ ์ ํ๊ตฐ ์์ฑ์ ๊ด๋ฆฌํ๊ธฐ ์ํ ๋์์ธ ํจํด์ ๋๋ค. ์ด ํ ํ๋ฆฟ์ ์ฌ์ฉํ ๋ ๋ค์์ ์ํํด์ผ ํฉ๋๋ค.- ์ ํ๊ตฐ ์์ฒด๋ฅผ ์ ์ํฉ๋๋ค. ๊ทธ ์ค ๋ ๊ฐ์ง๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
SpecificProductA1
,SpecificProductB1
SpecificProductA2
,SpecificProductB2
- ์ ํ๊ตฐ ๋ด์ ๊ฐ ์ ํ์ ๋ํด ์ถ์ ํด๋์ค(์ธํฐํ์ด์ค)๋ฅผ ์ ์ํฉ๋๋ค. ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ProductA
ProductB
- ๊ฐ ์ ํ๊ตฐ ๋ด์์ ๊ฐ ์ ํ์ 2๋จ๊ณ์์ ์ ์๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
- 2๋จ๊ณ์์ ์ ์ํ ๊ฐ ์ ํ์ ๋ํ ์์ฑ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ถ์ ํฉํ ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ์ด๋ฌํ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ProductA createProductA();
ProductB createProductB();
- ๊ฐ ๊ตฌํ์ด ๋์ผํ ์ ํ๊ตฐ์ ์ ํ ์์ฑ์ ์ ์ดํ๋๋ก ์ถ์ ํฉํ ๋ฆฌ ๊ตฌํ์ ๋ง๋ญ๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ถ์ ํฉํ ๋ฆฌ์ ๊ฐ ๊ตฌํ ๋ด์์ ๋ชจ๋ ์์ฑ ๋ฉ์๋๋ฅผ ๊ตฌํํ์ฌ ์ ํ์ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ์ด ์์ฑ๋๊ณ ๋ฐํ๋๋๋ก ํด์ผ ํฉ๋๋ค.
// ะะฟัะตะดะตะปะธะผ ะพะฑัะธะต ะธะฝัะตััะตะนัั ะฟัะพะดัะบัะพะฒ
public interface ProductA {}
public interface ProductB {}
// ะกะพะทะดะฐะดะธะผ ัะฐะทะปะธัะฝัะต ัะตะฐะปะธะทะฐัะธะธ (ัะตะผะตะนััะฒะฐ) ะฝะฐัะธั
ะฟัะพะดัะบัะพะฒ
public class SpecificProductA1 implements ProductA {}
public class SpecificProductB1 implements ProductB {}
public class SpecificProductA2 implements ProductA {}
public class SpecificProductB2 implements ProductB {}
// ะกะพะทะดะฐะดะธะผ ะฐะฑัััะฐะบัะฝัั ัะฐะฑัะธะบั
public interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// ะกะพะทะดะฐะดะธะผ ัะตะฐะปะธะทะฐัะธั ะฐะฑัััะฐะบัะฝะพะน ัะฐะฑัะธะบะธ ะดะปั ัะพะทะดะฐะฝะธั ะฟัะพะดัะบัะพะฒ ัะตะผะตะนััะฒะฐ 1
public class SpecificFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new SpecificProductA1();
}
@Override
public ProductB createProductB() {
return new SpecificProductB1();
}
}
// ะกะพะทะดะฐะดะธะผ ัะตะฐะปะธะทะฐัะธั ะฐะฑัััะฐะบัะฝะพะน ัะฐะฑัะธะบะธ ะดะปั ัะพะทะดะฐะฝะธั ะฟัะพะดัะบัะพะฒ ัะตะผะตะนััะฒะฐ 1
public class SpecificFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new SpecificProductA2();
}
@Override
public ProductB createProductB() {
return new SpecificProductB2();
}
}
์์
์๋ฃ๋ฅผ ํตํฉํ๋ ค๋ฉด ๋ค์ ๋ ๊ฐ์ง ์์ ์ ์ํํ ์ ์์ต๋๋ค.- Linux์์ ์๋ํ๋๋ก ์ปคํผ ์ฃผ๋ฌธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ์ ํฉ๋๋ค.
- ์์ ๋ง์ ์ถ์ ํฉํ ๋ฆฌ๋ฅผ ๋ง๋ค์ด ๋ชจ๋ ์ ๋ต์ ๋จ์๋ฅผ ์์ฐํ์ธ์. ์ด๋ ์ค์ ๊ตฐ๋๋ฅผ ์ด์ฉํ ์ญ์ฌ์ ์ ๋ต์ผ ์๋ ์๊ณ ์คํฌ, ๋์ํ, ์ํ๋ฅผ ์ด์ฉํ ํํ์ง์ผ ์๋ ์์ต๋๋ค. ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ๋น์ ์ด ๊ทธ๊ฒ์ด ํฅ๋ฏธ๋ก์ ๋ค๋ ๊ฒ์ ๋๋ค. ์ฐฝ์๋ ฅ์ ๋ฐํํ๊ณ , ์ฝ์์ ํ์ ๊ฒ์ํ๊ณ , ํจํด์ ์ฌ๋ฏธ์๊ฒ ๋ฐฐ์๋ณด์ธ์!
GO TO FULL VERSION