반응형
: 일련의 행동을 특정 리시버(받는자)와 연결시킴으로써 요구사항을 캡슐화 한 것.
배우게 될 내용.
- 메소드 호출을 캡슐화
- 캡슐화된 메소드 재사용
가정) 최신형 리모컨을 개발한다. 리모컨 안에는 일곱 가지 프로그래밍이 가능한 슬롯이 있습니다.
그 일곱 가지를 가지고 on / off 할 수 있는 스위치도 가지고 있습니다.
기능에 대해 얘기해보자면, 스마트홈 같은 집에 불켜기, 가스불 끄기, 욕조물 데우기 등의 기능이 있다고 치겠습니다.
이러한 메소드들을 캡슐화하고, 캡슐화된 메소드를 재사용 해보겠습니다.
예제 작성 1
: 리모컨 버튼이 하나만 있다고 생각하고 불을 키는 버튼을 가진 리모컨을 사용해 커맨드 패턴을 사용하겠습니다.
//커맨드 객체
public interface Command {
//실행 메소드
void execute();
}
//불을 키는 클래스
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
//불
public class Light {
// 켜짐
public String on() {
Log.d("abcd", "불 켜짐");
return "불 켜짐";
}
// 꺼짐
public String off() {
return "불 꺼짐";
}
}
//불을 키는 클래스
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
//리모컨
public class RemoteController {
Command command;
public void setCommand(Command command) {
this.command = command;
}
public void buttonClicked() {
command.execute();
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//리모컨 객체 생성
RemoteController remoteCon = new RemoteController();
// 불빛 객체
Light light = new Light();
// 불 키는 명령을 내리는 command 객체에 넣어줌
LightOnCommand lightOn = new LightOnCommand(light);
// command 설정
remoteCon.setCommand(lightOn);
// 클릭
remoteCon.buttonClicked();
}
}
결관 ; D/abcd: 불 켜짐
.
.
커맨드 패턴 : 커맨드 패턴을 이용하면 요구사항을 객체로 캡술화 할 수 있으며, 매개변수를 써서 여러가지 다른 요구사항을 집어 넣을 수도 있습니다. 또한 요청 내역을 큐(queue)에 저장하거나 로그로 기록할 수 있으며, 작업취소 기능도 지원 가능합니다.
.
.
.
.
.
.
.
.
바뀐 부분.
//null 방지를 위해 넣어줌.
public class NoCommand implements Command {
@Override
public void execute() {
Log.d("abcd", "null 방지");
}
}
noCommand 객체는 일종의 null객체입니다. 리턴할 객체는 없지만,
클라이언트 쪽에서 null을 처리하지 않아도 되도록 하고 싶을 때 null 객체를 활용하면 좋습니다.
(즉, 빈자리를 채우기 위한 용도일 뿐입니다.)
//커맨드 객체
public interface Command {
//실행 메소드
void execute();
//취소 메솓,
void undo();
}
//리모컨
public class RemoteController {
Command[] onCommands;
Command[] offCommands;
Command undoCommand;
public RemoteController() {
// 7개의 기능을 가진 버튼 on/off을 실행할 array[]
onCommands = new Command[7];
offCommands = new Command[7];
//null방지
Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}
//command 설정
public void setCommand(int slot, Command onCommand, Command offCommand) {
this.onCommands[slot] = onCommand;
this.offCommands[slot] = offCommand;
}
//on 버튼 클릭
public void onButtonClicked(int slot) {
this.onCommands[slot].execute();
//실행 후, 실행 취소를 누르면 바로 취소시키기 위해 해당 버튼의 [slot]을 준비시킴
undoCommand = onCommands[slot];
}
//off 버튼 클릭
public void offButtonClicked(int slot) {
this.offCommands[slot].execute();
undoCommand = offCommands[slot];
}
//취소 버튼 클릭
public void undoButtonClicked() {
undoCommand.undo();
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//리모컨 객체 생성
RemoteController remoteCon = new RemoteController();
// 불빛 객체
Light light = new Light();
// 불 키는 명령
LightOnCommand lightOn = new LightOnCommand(light);
// 불 끄는 명령
LightOffCommand lightOff = new LightOffCommand(light);
// command 설정
remoteCon.setCommand(0,lightOn,lightOff);
// 클릭
remoteCon.onButtonClicked(0);
remoteCon.offButtonClicked(0);
remoteCon.undoButtonClicked();
}
}
코틀린 코드
interface Command {
fun execute()
fun undo()
}
//
class LightOnCommand constructor(light: Light) :Command {
var light : Light? = null
init {
this.light = light
}
override fun execute() { light?.on() }
override fun undo() { light?.off() }
}
//
class LightOffCommand constructor(light:Light) : Command {
var light : Light? = null
init {
this.light = light
}
override fun execute() {
light?.off()
}
override fun undo() {
light?.on()
}
}
///
class NoCommand : Command {
override fun execute() {
TODO("Not yet implemented")
}
override fun undo() {
TODO("Not yet implemented")
}
}
class Light {
fun on() { Log.d("abcd", "불 켜기")}
fun off() {Log.d("abcd","불끄기")}
}
class RemoteController {
var onCommand: Array<Command>? = null
var offCommand: Array<Command>? = null
var undoCommand:Command? = null
init {
val noCommand = NoCommand()
//사이즈, 초기화
onCommand =Array(7, {noCommand})
offCommand = Array(7, {noCommand})
undoCommand = noCommand
}
fun setCommand(slot:Int, onCommand: Command, offCommand: Command) {
this.onCommand?.set(slot, onCommand)
this.offCommand?.set(slot, offCommand)
}
fun onButtonClicked(slot:Int) {
this.onCommand?.get(slot)!!.execute()
undoCommand = onCommand!![slot]
}
fun offButtonClicked(slot:Int) {
this.offCommand?.get(slot)!!.execute()
undoCommand = offCommand!![slot]
}
fun undoButtonClicked() {
undoCommand!!.undo()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val remoteCon = RemoteController()
val light:Light = Light()
var lightOn: LightOnCommand = LightOnCommand(light)
var lightOff: LightOffCommand = LightOffCommand(light)
remoteCon.setCommand(0,lightOn,lightOff)
remoteCon.onButtonClicked(0)
remoteCon.offButtonClicked(0)
remoteCon.undoButtonClicked()
}
}
반응형
'개발공부 > 디자인 패턴' 카테고리의 다른 글
자바 및 코틀린 퍼사드(facade) 패턴이란? (0) | 2022.02.08 |
---|---|
자바 및 코틀린 어댑터(adapter) 패턴이란? (0) | 2022.02.07 |
안드로이드 자바 MVVM패턴 이란? (0) | 2022.01.24 |
안드로이드 자바 MVP패턴 이란? (0) | 2022.01.23 |
안드로이드 자바 MVC 패턴이란? (0) | 2022.01.22 |