udemy(参考に記載)でC#のStatePatternを聴講し、普段使っているMatlabのAppDesignerに実装してみた。
仕様
On/Offボタン:Lowに遷移
Off以外のときに
Upボタン:Low→Middle→High→Low→…
Downボタン:High→Middle→Low→High→…
Maxボタン:Highに遷移
Minボタン:Lowに遷移
フォルダ直下のheater.txtにワット数を出力する。
Main GUI
Main.mlapp
properties (Access = private)
context_
end
methods (Access = private)
function context_StateChanged(app, src, evnt)
app.lbl_State.Text = app.context_.GetText();
end
end
% Callbacks that handle component events
methods (Access = private)
% initialize
function startupFcn(app)
movegui(app.UIFigure, 'center');
app.context_ = Context;
addlistener(app.context_, 'StateChanged', @app.context_StateChanged);
app.context_StateChanged();
end
% On/Offボタンクリック時のコールバック
function pb_OnOffButtonPushed(app, event)
app.context_.OnOff();
end
% Upボタンクリック時のコールバック
function pb_UpButtonPushed(app, event)
app.context_.Up();
end
% Downボタンクリック時のコールバック
function pb_DownButtonPushed(app, event)
app.context_.Down();
end
% Maxボタンクリック時のコールバック
function pb_MaxButtonPushed(app, event)
app.context_.Max();
end
% Minボタンクリック時のコールバック
function pb_MinButtonPushed(app, event)
app.context_.Min();
end
end
各Class
各State
Abstract (Interface)
IState.m
classdef IState < handle
properties
end
methods (Abstract = true)
UpState
DownState
OnOffState
GetText
GetCommand
end
methods (Static, Sealed = true)
function OffWarning()
warndlg('まずはOnにしてください')
end
end
end
実装
OffState.m
classdef OffState < IState
properties
end
methods (Access = public, Sealed = true)
function UpState(this, context)
this.OffWarning();
return;
end
function DownState(this, context)
this.OffWarning();
return;
end
function OnOffState(this, context)
context.ChangeState(LowState);
end
function out = GetCommand(this)
% なにか処理を行う。
out = {'Off'; '0W'};
end
function out = GetText(this)
out = 'Off';
end
end
methods (Static)
end
end
LowState.m
classdef LowState < IState
properties
end
methods (Access = public, Sealed = true)
function UpState(this, context)
context.ChangeState(MiddleState);
end
function DownState(this, context)
context.ChangeState(HighState);
end
function OnOffState(this, context)
context.ChangeState(OffState);
end
function out = GetCommand(this)
% なにか処理を行う。
out = {'Low'; '500W'};
end
function out = GetText(this)
out = 'Low';
end
end
methods (Static)
end
end
MiddleState.m
classdef MiddleState < IState
properties
end
methods (Access = public, Sealed = true)
function UpState(this, context)
context.ChangeState(HighState);
end
function DownState(this, context)
context.ChangeState(LowState);
end
function OnOffState(this, context)
context.ChangeState(OffState);
end
function out = GetCommand(this)
% なにか処理を行う。
out = {'Middle'; '1000W'};
end
function out = GetText(this)
out = 'Middle';
end
end
methods (Static)
end
end
HighState.m
classdef HighState < IState
properties
end
methods (Access = public, Sealed = true)
function UpState(this, context)
context.ChangeState(LowState);
end
function DownState(this, context)
context.ChangeState(MiddleState);
end
function OnOffState(this, context)
context.ChangeState(OffState);
end
function out = GetCommand(this)
% なにか処理を行う。
out = {'High'; '1500W'};
end
function out = GetText(this)
out = 'High';
end
end
methods (Static)
end
end
現在の状態Class
Context.m
classdef Context < handle
properties (SetAccess = private, GetAccess = private)
state_
end
events
StateChanged
end
methods (Access = public, Sealed = true)
function this = Context
this.state_ = OffState;
this.Send();
end
function Up(this)
this.state_.UpState(this);
this.Send();
end
function Down(this)
this.state_.DownState(this);
this.Send();
end
function OnOff(this)
this.state_.OnOffState(this);
this.Send();
end
function Max(this)
if isequal(this.state_, OffState)
this.state_.OffWarning();
return
end
this.ChangeState(HighState);
this.Send();
end
function Min(this)
if isequal(this.state_, OffState)
this.state_.OffWarning();
return
end
this.ChangeState(LowState);
this.Send();
end
function out = GetText(this)
out = this.state_.GetText();
end
function this = ChangeState(this, IState)
this.state_ = IState;
notify(this, 'StateChanged');
end
end
methods (Access = private)
function Send(this)
path = 'heater.txt';
writecell(this.state_.GetCommand(), path);
end
end
end