๊ด€๋ฆฌ ๋ฉ”๋‰ด

deVlog

[๋””์ž์ธ ํŒจํ„ด] ํ–‰์œ„ ํŒจํ„ด - Command Pattern (์ปค๋งจ๋“œ ํŒจํ„ด) ๋ณธ๋ฌธ

๐Ÿ› ๏ธ Software Architecture/Design Pattern

[๋””์ž์ธ ํŒจํ„ด] ํ–‰์œ„ ํŒจํ„ด - Command Pattern (์ปค๋งจ๋“œ ํŒจํ„ด)

์€๋ฃจ๋ฐ 2025. 4. 2. 21:03

๋ชฉ์ฐจ

     

    ๐Ÿ“‡ ๊ฐœ์š”

    ์ปค๋งจ๋“œ ํŒจํ„ด(Command Pattern)์€ ์š”์ฒญ์„ ๊ฐ์ฒด๋กœ ์บก์Аํ™”ํ•˜์—ฌ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋งŒ๋“ค๊ณ , ์š”์ฒญ ๋‚ด์—ญ์„ ํ์— ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ๋กœ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ํ–‰๋™ ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค. ์ฆ‰, ์‹คํ–‰๋  ๊ธฐ๋Šฅ์„ ์บก์Аํ™”ํ•˜์—ฌ ํ˜ธ์ถœ์ž(Invoker)์™€ ์ˆ˜์‹ ์ž(Receiver) ์‚ฌ์ด์˜ ์˜์กด์„ฑ์„ ์ œ๊ฑฐํ•˜๋Š” ํŒจํ„ด์ด๋‹ค.

     

    ํŠน์ง•

    • ๋ช…๋ น(์š”์ฒญ)์„ ๊ฐ์ฒด๋กœ ํ‘œํ˜„ํ•˜์—ฌ ์บก์Аํ™”ํ•œ๋‹ค.
    • ์‹คํ–‰๋  ๊ธฐ๋Šฅ์˜ ๋ณ€๊ฒฝ์—๋„ ํ˜ธ์ถœ์ž ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
    • ๋ช…๋ น์˜ ์ €์žฅ, ๋กœ๊น…, ์ทจ์†Œ ๋“ฑ ๋‹ค์–‘ํ•œ ํ™•์žฅ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    ๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป ์ฝ”๋“œ๋กœ ์•Œ์•„๋ณด์ž

    ๋ฆฌ๋ชจ์ปจ์œผ๋กœ ๋‹ค์–‘ํ•œ ๊ฐ€์ „์ œํ’ˆ์„ ์ œ์–ดํ•˜๋Š” ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์ปค๋งจ๋“œ ํŒจํ„ด์„ ์‚ดํŽด๋ณด์ž.

    // 1. ์ปค๋งจ๋“œ ์ธํ„ฐํŽ˜์ด์Šค
    interface Command {
        void execute();
        void undo();
    }
    
    // 2. ์ˆ˜์‹ ์ž(Receiver) ํด๋ž˜์Šค๋“ค
    class Light {
        private String location;
        
        public Light(String location) {
            this.location = location;
        }
        
        public void on() {
            System.out.println(location + " ์กฐ๋ช…์ด ์ผœ์กŒ์Šต๋‹ˆ๋‹ค.");
        }
        
        public void off() {
            System.out.println(location + " ์กฐ๋ช…์ด ๊บผ์กŒ์Šต๋‹ˆ๋‹ค.");
        }
    }
    
    class Television {
        public void on() {
            System.out.println("TV๊ฐ€ ์ผœ์กŒ์Šต๋‹ˆ๋‹ค.");
        }
        
        public void off() {
            System.out.println("TV๊ฐ€ ๊บผ์กŒ์Šต๋‹ˆ๋‹ค.");
        }
        
        public void setChannel(int channel) {
            System.out.println("TV ์ฑ„๋„์ด " + channel + "๋ฒˆ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
        }
    }
    
    // 3. ๊ตฌ์ฒด์ ์ธ ์ปค๋งจ๋“œ ํด๋ž˜์Šค๋“ค
    class LightOnCommand implements Command {
        private Light light;
        
        public LightOnCommand(Light light) {
            this.light = light;
        }
        
        @Override
        public void execute() {
            light.on();
        }
        
        @Override
        public void undo() {
            light.off();
        }
    }
    
    class LightOffCommand implements Command {
        private Light light;
        
        public LightOffCommand(Light light) {
            this.light = light;
        }
        
        @Override
        public void execute() {
            light.off();
        }
        
        @Override
        public void undo() {
            light.on();
        }
    }
    
    class TVOnCommand implements Command {
        private Television tv;
        
        public TVOnCommand(Television tv) {
            this.tv = tv;
        }
        
        @Override
        public void execute() {
            tv.on();
        }
        
        @Override
        public void undo() {
            tv.off();
        }
    }
    
    class TVOffCommand implements Command {
        private Television tv;
        
        public TVOffCommand(Television tv) {
            this.tv = tv;
        }
        
        @Override
        public void execute() {
            tv.off();
        }
        
        @Override
        public void undo() {
            tv.on();
        }
    }
    
    class TVChangeChannelCommand implements Command {
        private Television tv;
        private int channel;
        private int previousChannel;
        
        public TVChangeChannelCommand(Television tv, int channel) {
            this.tv = tv;
            this.channel = channel;
        }
        
        @Override
        public void execute() {
            // ์‹ค์ œ ๊ตฌํ˜„์—์„œ๋Š” ์ด์ „ ์ฑ„๋„์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ
            tv.setChannel(channel);
        }
        
        @Override
        public void undo() {
            // ์ด์ „ ์ฑ„๋„๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ธฐ๋Šฅ (์—ฌ๊ธฐ์„œ๋Š” ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„)
            System.out.println("์ด์ „ ์ฑ„๋„๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค.");
        }
    }
    
    // 4. ํ˜ธ์ถœ์ž(Invoker) ํด๋ž˜์Šค
    class RemoteControl {
        private Command[] onCommands;
        private Command[] offCommands;
        private Command undoCommand;
        
        public RemoteControl() {
            onCommands = new Command[5];
            offCommands = new Command[5];
            
            // NoCommand ๊ฐ์ฒด๋กœ ์ดˆ๊ธฐํ™”
            Command noCommand = new NoCommand();
            for (int i = 0; i < 5; i++) {
                onCommands[i] = noCommand;
                offCommands[i] = noCommand;
            }
            undoCommand = noCommand;
        }
        
        public void setCommand(int slot, Command onCommand, Command offCommand) {
            onCommands[slot] = onCommand;
            offCommands[slot] = offCommand;
        }
        
        public void onButtonWasPushed(int slot) {
            onCommands[slot].execute();
            undoCommand = onCommands[slot];
        }
        
        public void offButtonWasPushed(int slot) {
            offCommands[slot].execute();
            undoCommand = offCommands[slot];
        }
        
        public void undoButtonWasPushed() {
            undoCommand.undo();
        }
        
        @Override
        public String toString() {
            StringBuffer sb = new StringBuffer();
            sb.append("\n------ ๋ฆฌ๋ชจ์ปจ ------\n");
            for (int i = 0; i < onCommands.length; i++) {
                sb.append("[slot " + i + "] " + onCommands[i].getClass().getName() + "   " 
                        + offCommands[i].getClass().getName() + "\n");
            }
            sb.append("[undo] " + undoCommand.getClass().getName() + "\n");
            return sb.toString();
        }
    }
    
    // Null Object ํŒจํ„ด์„ ์ ์šฉํ•œ NoCommand ํด๋ž˜์Šค
    class NoCommand implements Command {
        @Override
        public void execute() {
            // ์•„๋ฌด ๋™์ž‘๋„ ํ•˜์ง€ ์•Š์Œ
        }
        
        @Override
        public void undo() {
            // ์•„๋ฌด ๋™์ž‘๋„ ํ•˜์ง€ ์•Š์Œ
        }
    }
    
    // 5. ํด๋ผ์ด์–ธํŠธ
    public class CommandPatternExample {
        public static void main(String[] args) {
            // ๋ฆฌ๋ชจ์ปจ ์ƒ์„ฑ
            RemoteControl remoteControl = new RemoteControl();
            
            // ์ˆ˜์‹ ์ž ๊ฐ์ฒด๋“ค ์ƒ์„ฑ
            Light livingRoomLight = new Light("๊ฑฐ์‹ค");
            Light kitchenLight = new Light("์ฃผ๋ฐฉ");
            Television tv = new Television();
            
            // ์ปค๋งจ๋“œ ๊ฐ์ฒด๋“ค ์ƒ์„ฑ
            LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
            LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
            
            LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
            LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);
            
            TVOnCommand tvOn = new TVOnCommand(tv);
            TVOffCommand tvOff = new TVOffCommand(tv);
            TVChangeChannelCommand tvChannel9 = new TVChangeChannelCommand(tv, 9);
            
            // ๋ฆฌ๋ชจ์ปจ์— ์ปค๋งจ๋“œ ์„ค์ •
            remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
            remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff);
            remoteControl.setCommand(2, tvOn, tvOff);
            
            // ๋ฆฌ๋ชจ์ปจ ์ •๋ณด ์ถœ๋ ฅ
            System.out.println(remoteControl);
            
            // ๋ฆฌ๋ชจ์ปจ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๊ธฐ
            System.out.println("------ ๋ฆฌ๋ชจ์ปจ ๋ฒ„ํŠผ ํ…Œ์ŠคํŠธ ------");
            remoteControl.onButtonWasPushed(0);  // ๊ฑฐ์‹ค ์กฐ๋ช… ์ผœ๊ธฐ
            remoteControl.offButtonWasPushed(0); // ๊ฑฐ์‹ค ์กฐ๋ช… ๋„๊ธฐ
            remoteControl.onButtonWasPushed(1);  // ์ฃผ๋ฐฉ ์กฐ๋ช… ์ผœ๊ธฐ
            remoteControl.undoButtonWasPushed(); // ์ฃผ๋ฐฉ ์กฐ๋ช… ๋„๊ธฐ (์‹คํ–‰ ์ทจ์†Œ)
            
            remoteControl.onButtonWasPushed(2);  // TV ์ผœ๊ธฐ
            // TV ์ฑ„๋„ ๋ณ€๊ฒฝ์€ ๋ณ„๋„๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ
            tvChannel9.execute();
            remoteControl.offButtonWasPushed(2); // TV ๋„๊ธฐ
        }
    }
    
    • Command ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์‹คํ–‰(execute())๊ณผ ์‹คํ–‰ ์ทจ์†Œ(undo()) ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค.
    • ์ˆ˜์‹ ์ž ํด๋ž˜์Šค(Light, Television)๋Š” ์‹ค์ œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค.
    • ๊ตฌ์ฒด์ ์ธ ์ปค๋งจ๋“œ ํด๋ž˜์Šค๋“ค(LightOnCommand, TVOffCommand ๋“ฑ)์€ ์ˆ˜์‹ ์ž ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๋ฉฐ ์ด๋ฅผ ํ†ตํ•ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
    • ํ˜ธ์ถœ์ž(Invoker) ์—ญํ• ์„ ํ•˜๋Š” RemoteControl์€ Command ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ณ  ํ•„์š”ํ•œ ์‹œ์ ์— ์‹คํ–‰ํ•œ๋‹ค.
    • NoCommand ํด๋ž˜์Šค๋Š” Null Object ํŒจํ„ด์„ ์ ์šฉํ•˜์—ฌ null ์ฒดํฌ๋ฅผ ์ค„์ด๊ณ  ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™”ํ•œ๋‹ค.

     

    โ˜˜๏ธ ์žฅ/๋‹จ์ 

    โœ… ์žฅ์ 

    1. ํ˜ธ์ถœ์ž์™€ ์ˆ˜์‹ ์ž์˜ ๋ถ„๋ฆฌ(Decoupling)
      • ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ๊ฐ์ฒด(ํ˜ธ์ถœ์ž)์™€ ์‹ค์ œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ์ฒด(์ˆ˜์‹ ์ž)๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค.
      • ์ด๋กœ ์ธํ•ด ์‹œ์Šคํ…œ์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„์ง€๊ณ  ์œ ์—ฐ์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.
    2. ๋ช…๋ น์˜ ํ™•์žฅ ์šฉ์ด์„ฑ
      • ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ์ƒˆ๋กœ์šด ๋ช…๋ น์„ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
      • ์˜ˆ๋ฅผ ๋“ค์–ด, ์—์–ด์ปจ ์ œ์–ด ๋ช…๋ น์„ ์ถ”๊ฐ€ํ•˜๋”๋ผ๋„ RemoteControl ํด๋ž˜์Šค๋Š” ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
    3. ๋ช…๋ น์˜ ์กฐํ•ฉ ๊ฐ€๋Šฅ
      • ์—ฌ๋Ÿฌ ๋ช…๋ น์„ ์กฐํ•ฉํ•˜์—ฌ ๋ณตํ•ฉ ๋ช…๋ น(Macro Command)์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
      • ์˜ˆ: "์˜ํ™” ๋ชจ๋“œ" ๋ฒ„ํŠผ์œผ๋กœ ์กฐ๋ช… ๋„๊ธฐ, TV ์ผœ๊ธฐ, ๋ณผ๋ฅจ ์กฐ์ • ๋“ฑ์„ ํ•œ ๋ฒˆ์— ์‹คํ–‰
    4. ์‹คํ–‰ ์ทจ์†Œ(Undo) ๋ฐ ์žฌ์‹คํ–‰(Redo) ์ง€์›
      • ๋ช…๋ น ๊ฐ์ฒด๊ฐ€ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋ฏ€๋กœ ์ด์ „ ์ž‘์—…์„ ์ทจ์†Œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
      • ๋ช…๋ น ์‹คํ–‰ ๊ธฐ๋ก์„ ์Šคํƒ์— ์ €์žฅํ•˜๋ฉด ๋‹ค์ค‘ ์‹คํ–‰ ์ทจ์†Œ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
    5. ๋ช…๋ น ๋กœ๊น… ๋ฐ ํŠธ๋žœ์žญ์…˜ ์ง€์›
      • ๋ช…๋ น์„ ๊ฐ์ฒด๋กœ ์ €์žฅํ•˜๋ฉด ๋ช…๋ น์˜ ๋กœ๊น…๊ณผ ์‹œ์Šคํ…œ ๋ณต๊ตฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.
      • ํŠธ๋žœ์žญ์…˜ ์‹œ์Šคํ…œ์—์„œ๋Š” ๋ช…๋ น ์ง‘ํ•ฉ์„ ์ €์žฅํ•˜๊ณ  ์‹คํŒจ ์‹œ ๋กค๋ฐฑํ•  ์ˆ˜ ์žˆ๋‹ค.

    โŒ ๋‹จ์ 

    1. ํด๋ž˜์Šค ์ˆ˜ ์ฆ๊ฐ€
      • ๊ฐ ๋ช…๋ น๋งˆ๋‹ค ๋ณ„๋„์˜ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ ์‹œ์Šคํ…œ์˜ ํด๋ž˜์Šค ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ๋‹ค.
      • ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์—๋„ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฏ€๋กœ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
    2. ๋ณต์žก์„ฑ ์ฆ๊ฐ€
      • ๋‹จ์ˆœํ•œ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ์—ฌ๋Ÿฌ ํด๋ž˜์Šค์˜ ์ƒํ˜ธ์ž‘์šฉ์œผ๋กœ ๋ณ€ํ•˜๋ฏ€๋กœ ์‹œ์Šคํ…œ์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
      • ํŠนํžˆ ์ฒ˜์Œ ํŒจํ„ด์„ ์ ‘ํ•˜๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค.
    3. ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ฆ๊ฐ€
      • ๊ฐ ๋ช…๋ น๋งˆ๋‹ค ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
      • ๋ช…๋ น์„ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
    4. ๋””๋ฒ„๊น… ์–ด๋ ค์›€
      • ํ˜ธ์ถœ ์ฒด์ธ์ด ๊ธธ์–ด์ง€๋ฉด ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค.
      • ํŠนํžˆ undo/redo ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฉด ์ƒํƒœ ์ถ”์ ์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

     

    ๐Ÿ“Œ ์ •๋ฆฌ

    ์ปค๋งจ๋“œ ํŒจํ„ด์€ ์š”์ฒญ์„ ๊ฐ์ฒด๋กœ ์บก์Аํ™”ํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐํ•œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

    ์ด ํŒจํ„ด์€ ํ˜ธ์ถœ์ž์™€ ์ˆ˜์‹ ์ž๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ , ๋ช…๋ น์˜ ์‹คํ–‰, ์ทจ์†Œ, ๋กœ๊น…, ํŠธ๋žœ์žญ์…˜ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค. ๋Œ€์‹  ํด๋ž˜์Šค ์ˆ˜๊ฐ€ ๋งŽ์•„์ง€๊ณ  ์‹œ์Šคํ…œ์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

     

    โœ… ์–ธ์ œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„๊นŒ?

    • ์ž‘์—…์— ๋Œ€ํ•œ ์‹คํ–‰ ์ทจ์†Œ(undo)๊ฐ€ ํ•„์š”ํ•  ๋•Œ
    • ๋ช…๋ น ๊ธฐ๋ก, ๋กœ๊น…, ํŠธ๋žœ์žญ์…˜ ์‹œ์Šคํ…œ์ด ํ•„์š”ํ•  ๋•Œ
    • ๋ช…๋ น์˜ ์ง€์—ฐ ์‹คํ–‰์ด๋‚˜ ์Šค์ผ€์ค„๋ง์ด ํ•„์š”ํ•  ๋•Œ
    • ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ๊ฐ์ฒด๋ฅผ ํ†ตํ•œ ๋™์ž‘ ์ˆ˜ํ–‰์ด ํ•„์š”ํ•  ๋•Œ
    • ๋ช…๋ น์„ ํ์— ์ €์žฅํ•˜๊ณ  ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•  ๋•Œ

    โŒ ์–ธ์ œ ํ”ผํ•ด์•ผ ํ• ๊นŒ?

    • ๋‹จ์ˆœํ•œ ์ž‘์—…์— ๊ณผ๋„ํ•œ ๋ณต์žก์„ฑ์„ ์ถ”๊ฐ€ํ•  ๋•Œ
    • ๋ช…๋ น ๊ฐ์ฒด๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์ ธ์„œ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์šธ ๋•Œ
    • ์‹คํ–‰ ์ทจ์†Œ๋‚˜ ๋กœ๊น… ๋“ฑ์˜ ๊ธฐ๋Šฅ์ด ํ•„์š” ์—†์„ ๋•Œ
    • ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜๊ณ  ๋ช…๋ น ๊ฐ์ฒด์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฌธ์ œ๊ฐ€ ๋  ๋•Œ

     

    ๐Ÿ“‹ ์ฐธ๊ณ