[디자인 패턴] - Command

leehyunjon·2022년 11월 18일
0

Java

목록 보기
5/7

행위 패턴

행위 패턴이란, 행위를 클래스로 만들어 캡슐화하는 패턴입니다.

객체A가 객체B의 메소드를 실행하기 위해서는 객체A는 객체B를 의존해야합니다.
그렇게 된다면 기능의 수정이 발생할때, 객체A에서도 수정이 이루어져야하기 때문에 OOP원칙을 위배하게 됩니다.

예를 들어 Client, , Heater클래스가 존재한다고 하겠습니다.

	public class Client{
		void talk(){
			Heater heater = new Heater();
			Genie genie = new Genie();
			
			genie.setHeater(heater);
			genie.talk();
		}
	}

	public class Genie{
		Heater heater;
		void setHeater(Heater heater){
			this.heater = heater;
		}
		void talk(){
			this.heater.powerOn();
		}
	}

	public class Heater{
		void powerOn(){
			System.out.println("히터 켜기!");
		}
	}

Client가 Genie에게 Heater를 틀어달라고 요구할때, Genie가 Heater의 기능을 사용하기 위해 Heater를 의존하고 있습니다.
이 상태에서 Heater가 아닌 Lamp가 추가되어 Genie가 Lamp를 틀어주는 기능을 추가하기 위해서는 Genie가 Lamp도 의존하게되어 Genie내부에 Lamp를 실행시키는 코드가 추가되어 수정되게 됩니다.
결국, OCP를 위반하게 되는것입니다.

이를 해결하기 위해 Heater와 Lamp와 같이 Genie가 의존하는 것들을 캡슐화하여야합니다.

	public interface Command{
		void run();
	}

	public class HeaterCommand implements Command{
		Heater heater;
		void setHeater(Heater heater){
			this.heater = heater;
		}
		@Override
		public void run() {
			this.heater.powerOn();
		}
	}

	public class Heater{
		public void powerOn(){
			System.out.println("히터 켜기!");
		}
	}

	public class LampCommand implements Command{
		Lamp lamp;

		void setLamp(Lamp lamp){
			this.lamp = lamp;
		}
		@Override
		public void run() {
			this.lamp.turnOn();
		}
	}

	public class Lamp{
		public void turnOn(){
			System.out.println("램프 켜기!");
		}
	}

	public class Genie{
		Command command;

		public void setCommand(Command command){
			this.command = command;
		}

		public void talk(){
			this.command.run();
		}
	}

	public class Client{
		public void talk(){
			Genie genie = new Genie();

			HeaterCommand heaterCommand = new HeaterCommand();
			Heater heater = new Heater();
			heaterCommand.setHeater(heater);

			genie.setCommand(heaterCommand);
			genie.talk();

			LampCommand lampCommand = new LampCommand();
			Lamp lamp = new Lamp();
			lampCommand.setLamp(lamp);

			genie.setCommand(lampCommand);
			genie.talk();
		}
	}

Genie가 Heater와 Lamp의 행위를 수행하는 것을 HeaterCommand와 LampCommand로 클래스화하고 Command 인터페이스로 정의합니다.
Genie가 HeaterCommand와 LampCommand를 통해 Heater와 Lamp의 행위를 수행함으로써 Genie가 Heater와 Lamp와의 의존성을 제거된 상태로 행위를 수행할 수 있게 됩니다.

위와 같이 표현할 수 있습니다.

해당 정리는 victolee님의 블로그 내용을 보고 학습하고 개인적으로 정리하는 것이기 때문에 유사한 내용이 많다는 점 알려드립니다.


Reference

https://victorydntmd.tistory.com/295

https://gmlwjd9405.github.io/2018/07/07/command-pattern.html

https://www.youtube.com/watch?v=lJES5TQTTWE

profile
내 꿈은 좋은 개발자

0개의 댓글