연습문제 1. TwoButtonController 클래스를 구현.
* 기존코드
class TwoButtonController{
private TV tv;
public TwoButtonController(TV tv) {
this.tv = tv;
}
public void button1Pressed() {
tv.power();
}
public void button2Pressed() {
tv.mute();
}
}
class TV{
private boolean powerOn = false;
private boolean muteOn =false;
public void power() {
powerOn =! powerOn;
if(powerOn) {
System.out.println("power on");
} else {
System.out.println("power off");
}
}
public void mute() {
if(!powerOn) return;
muteOn =! muteOn;
if(muteOn) {
System.out.println("mute on");
} else {
System.out.println("mute off");
}
}
}
* 다음 요구사항을 충족할 수 있도록 TwoButtonController 클래스를 개선하라.
1) TwoButtonController 클래스를 이용해 TV전원과 음소거를 제어할 수 있다.
2) TwoButtonController 클래스의 각 버튼을 눌렀을 때 실행되는 기능은 전원과 음소거 중에서 임의의 방식으로 결정 할 수 있다. 버튼이 2개 (button1, button2) 고 동작할 수 있는 기능이 2가지(전원, 음소거)이므로 4가지 조합이 가능해야 한다.
3) TwoButtonController 클래스는 각 버튼을 눌렀을 때 동작하는 기능을 변경할 수 있어야 한다. 그러나 TwoButtonController 클래스의 코드가 변경되지 않도록 해야 한다.
* 코드 구현
* Command.java
public interface Command {
public abstract void execute();
}
* PowerOnCommand.java
public class PowerOnCommand implements Command {
private PowerButton powerbutton;
public PowerOnCommand(PowerButton powerbutton) {
this.powerbutton = powerbutton;
}
@Override
public void execute() {
powerbutton.powerOn();
}
}
* PowerOffCommand.java
public class PowerOffCommand implements Command {
private PowerButton powerbutton;
public PowerOffCommand(PowerButton powerbutton) {
this.powerbutton = powerbutton;
}
@Override
public void execute() {
powerbutton.powerOff();
}
}
* MuteOnCommand.java
public class MuteOnCommand implements Command {
private MuteButton mutebutton;
public MuteOnCommand(MuteButton muteButton) {
this.mutebutton = muteButton;
}
@Override
public void execute() {
mutebutton.muteOn();
}
}
* MuteOffCommand.java
public class MuteOffCommand implements Command {
private MuteButton mutebutton;
public MuteOffCommand(MuteButton muteButton) {
this.mutebutton = muteButton;
}
@Override
public void execute() {
mutebutton.muteOff();
}
}
* PowerButton.java
class PowerButton {
public void powerOn() {
System.out.println("power on");
}
public void powerOff() {
System.out.println("power off");
}
}
* MuteButton.java
class MuteButton {
public void muteOff() {
System.out.println("mute off");
}
public void muteOn() {
System.out.println("mute on");
}
}
* TwoButtonController.java
//그대로 있어야 되는 코드. 변경은 Concrete Command 에서 진행된다.
public class TwoButtonController {
private Command powerCommand;
private Command muteCommand;
public TwoButtonController(Command firstCommand,Command secondCommand) {
setCommand(firstCommand, secondCommand);
}
public void setCommand(Command firstCommand,Command secondCommand) {
this.powerCommand = firstCommand;
this.muteCommand = secondCommand;
}
public void powerBtnPressed() {
powerCommand.execute();
}
public void muteBtnPressed() {
muteCommand.execute();
}
}
* 실행할 Main클래스
public class Main {
public static void main(String[] args) {
PowerButton powerButton = new PowerButton();
MuteButton muteButton = new MuteButton();
Command powerOnButton = new PowerOnCommand(powerButton);
Command powerOffButton = new PowerOffCommand(powerButton);
Command muteOnButton = new MuteOnCommand(muteButton);
Command muteOffButton = new MuteOffCommand(muteButton);
//4가지의 경우의 만들기.
TwoButtonController btn1 = new TwoButtonController(powerOnButton,muteOnButton);
btn1.powerBtnPressed();
btn1.muteBtnPressed();
btn1.setCommand(powerOffButton, muteOffButton);
btn1.powerBtnPressed();
btn1.muteBtnPressed();
btn1.setCommand(powerOnButton, muteOffButton);
btn1.powerBtnPressed();
btn1.muteBtnPressed();
btn1.setCommand(powerOffButton, muteOnButton);
btn1.powerBtnPressed();
btn1.muteBtnPressed();
}
}
UML 구조는 다음과 같다.
하지만 이방식은 TV라는 recevier 로 받지 않고, TwoButtonController 에 대해서 변경사항이 생길 수 있는 코드 이기 때문에 완벽한 설계가 아니다. 버튼 자체를 관리하지않고, TV로 관리를 하는 것이다.
다음 문제를 해결하자면 이렇다.
* 코드구현
class TV{
private boolean powerOn = false;
private boolean muteOn = false;
public void power() {
powerOn =! powerOn;
if(powerOn) {
System.out.println("power on");
} else {
System.out.println("power off");
}
}
public void mute() {
if(!powerOn) return;
muteOn =! muteOn;
if(muteOn) {
System.out.println("mute on");
} else {
System.out.println("mute off");
}
}
}
interface Command {
public abstract void execute();
}
class PowerCommand implements Command {
private TV tv;
public PowerCommand(TV tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.power();
}
}
class PowerOffCommand implements Command {
private PowerButton powerbutton;
public PowerOffCommand(PowerButton powerbutton) {
this.powerbutton = powerbutton;
}
@Override
public void execute() {
powerbutton.powerOff();
}
}
class MuteCommand implements Command {
private TV tv;
public MuteCommand(TV tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.mute();
}
}
class PowerButton {
public void powerOn() {
System.out.println("power on");
}
public void powerOff() {
System.out.println("power off");
}
}
class MuteButton {
public void muteOff() {
System.out.println("mute off");
}
public void muteOn() {
System.out.println("mute on");
}
}
//그대로 있어야 되는 코드. 변경은 Concrete Command 에서 진행된다.
class TwoButtonController {
private Command command1;
private Command command2;
public void setCommand(Command command1,Command command2) {
this.command1 = command1;
this.command2 = command2;
}
public void button1Pressed() {
command1.execute();
}
public void button2Pressed() {
command2.execute();
}
}
public class Main {
public static void main(String[] args) {
TV tv = new TV();
TwoButtonController rc = new TwoButtonController();
Command powerCommand = new PowerCommand(tv);
//2개의 버튼에 동일한 powerCommand 객체를 전달함.
rc.setCommand(powerCommand, powerCommand);
rc.button1Pressed();
//button2, button1은 동일한 powerCommand 객체를 공유한다.
rc.button2Pressed(); //off
rc.button1Pressed();
rc.button1Pressed();
rc.button2Pressed();
rc.button1Pressed();
rc.button1Pressed();
System.out.println();
Command muteCommand = new MuteCommand(tv);
rc.setCommand(powerCommand, muteCommand );
rc.button2Pressed(); //off
rc.button1Pressed();
rc.button1Pressed();
rc.button2Pressed();
rc.button1Pressed();
}
}
UML 구조는 다음과 같다.
'Backend > Java Design Pattern' 카테고리의 다른 글
[JAVA 디자인 패턴] 싱글톤 패턴 (Singleton Pattern) (1) | 2020.12.17 |
---|---|
[JAVA 디자인 패턴] 커맨드 패턴 (Command Pattern) (0) | 2020.12.16 |
[JAVA 디자인 패턴] 스트래티지 패턴 ( Strategy Pattern) (4) | 2020.07.16 |