06 Mar 2014, 13:09

簡潔さは力なり!Rubyでステートパターン(State Pattern)を実装する

Rubyでステートパターンを勉強したので、その学習メモです。

サンプルは前回の記事を発展させたもの。

ステート・パターンとは

状態遷移をわかりやすく実装するためのパターン。

各状態をクラスで定義する。各状態は、抽象的なスーパークラスのサブクラスになる。

Spec

以下のような仕様を実装したい。

停止中に再生ボタンをクリックと動作中を表示
停止中に停止ボタンをクリックとなにも表示しない
動作中に再生ボタンをクリックと一時停止を表示
動作中に停止ボタンをクリックと停止を表示
一時停止中に再生ボタンをクリックする動作中を表示
一時停止中に停止ボタンをクリックする停止中を表示

状態は、停止中、一時停止中、実行中の3つ。この3つをクラスにする。

実装比較

普通の実装

<div class="outline-text-3" id="text-3-1">
  <p>
    if文が多いですね。
  </p>

  <p>
  </p>

  <p>
    ここで、さらにBoot中、Shutdown中なんて2つの状態追加がはいったらなかなか死ねます。
  </p></p>
</div></p>

パターン適用後

<div class="outline-text-3" id="text-3-2">
</div></p>

感動のボイント

感動のポイントをアピール。自分はここに感動した。


  def start

    if (@status == OFFLINE)
      @status = ONLINE
      @textValue = "動作中"
      return
    end

    if (@status == ONLINE)
      @status = SUSPEND
      @textValue = "一時停止中"
      return
    end

    if (@status == SUSPEND)
      @status = ONLINE
      @textValue = "動作中"
      return
    end
  end

  def stop

    if (@status == ONLINE)
      @status = OFFLINE
      @textValue = "停止中"
      return
    end

    if (@status == SUSPEND)
      @status = OFFLINE
      @textValue = "停止中"
      return
    end
  end

  def start
    @status = @status.start
  end

  def stop
    @status = @status.stop
  end

なんという簡潔さだろうか!ふるえちゃう。

06 Mar 2014, 11:43

[RubyTk]定期実行処理についてのメモ(Thread, TkAfter)

RubyTkでなにかの監視処理を実施する方法を調べたことのメモです。

RubyTk内でsleepが使えない

RubyTkでは、画面表示のために、Tk.mainloopを持ちいる。

これはメインスレッドで動作するため、 sleepをしてしまうとメインスレッドをその処理占有してしまい、 RubyTkをつかった描写ができない。また、逆もしかりである。

TkAfterをつかう

<div class="outline-text-3" id="text-1-1">
  <p>
    RubyTkでタイマ制御や定期監視のようなsleepに関わる処理に利用するライブラリがTkAfter.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://www.dumbo.ai.kyutech.ac.jp/nomura-ken/kajiyama/ruby_tk/after.html">http://www.dumbo.ai.kyutech.ac.jp/nomura-ken/kajiyama/ruby_tk/after.html</a>
    </li>
  </ul>

  <p>
    使用例は以下のとおり。
  </p>

  <p>
  </p>

  <p>
    タイマ制御がTkライブラリに依存してしまうのが個人的には気にくわなかった。
  </p>

  <p>
    なので、別の方法を考える。
  </p></p>
</div></p>

Threadをつかう

<div class="outline-text-3" id="text-1-2">
  <p>
    RubyのThread機能を利用して、別スレッドで定期的な処理を動かす。
  </p>

  <p>
    定期的な通知には、observerライブラリを利用する。
  </p>

  <p>
  </p>

  <p>
    どちらも実現したいことは同じだけれども、2つめのアーキの方が好きだ。
  </p></p>
</div></p>

05 Mar 2014, 12:29

[RubyTk] GUIアーキテクチャの定番MVCをRubyTkで実装してみる

MVCについて勉強したので、実際にRubyTkに応用してみる。

MVCとは

MVCとは、アーキテクチャの一つ。 Model-View-Controllerの略。 ユーザ・インタフェースをもつアプリケーションをうまくつくるための設計方法。

詳しい解説は、リンク先に譲るとする。

MVCアーキを利用すると、

  • 仕様変更につよい
  • 移植がしやすい

などのメリットがある。

また、テストが書きやすいという利点もある。 RubyTkライブラリがからむとviewのテストがかけない。 tkライブラリは論理的な処理から切り離したい。

MVC実装例

ボタンをおすと、ファイルからデータを読み出して、画面に表示するアプリケーションをつくる。

MVC以前

<div class="outline-text-3" id="text-2-1">
  <p>
    普通の実装。
  </p>

  <p>
    </div>
  </p>
</div>

<div id="outline-container-sec-2-2" class="outline-3">
  <h3 id="sec-2-2">
    MVCの実装
  </h3>

  <div class="outline-text-3" id="text-2-2">
    <p>
      Model, View, Controllerの3つにクラスを分割して実装。
    </p>

    <p>
      </div>
    </p>
  </div>

  <div id="outline-container-sec-2-3" class="outline-3">
    <h3 id="sec-2-3">
      proc, lambdaを導入する
    </h3>

    <div class="outline-text-3" id="text-2-3">
      <p>
        上の例だと、ViewとControllerの間に依存関係がある。これをなくしたい。
      </p>

      <p>
        Rubyでコールバックやハンドラの仕組みを導入するためにはどうすればいいのだろうか?
      </p>

      <p>
        答えは、procやlambdaを利用すればうまくできた!といっても、完全に依存関係がなくなったわけではないけど。
      </p>

      <p>
        感性的にこっちの方が美しく感じる。
      </p>

      <p>
        </div>
      </p>
    </div>

    <div id="outline-container-sec-2-4" class="outline-3">
      <h3 id="sec-2-4">
        Links
      </h3>

      <div class="outline-text-3" id="text-2-4">
        <ul class="org-ul">
          <li>
            <a href="http://stackoverflow.com/questions/1677861/how-to-implement-a-callback-in-ruby">How to implement a &#8220;callback&#8221; in Ruby? &#8211; Stack Overflow</a>
          </li>
        </ul>
      </div></p>
    </div></p>
  </div>