SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

C++/CX: Windows 8 ストアアプリことはじめ (2)

データ・バインディングのキホン

list-4
// BoundedCounterTest.cpp
#include "pch.h"
#include "CppUnitTest.h"
#include "CounterLib/CounterLib.h" // 追加

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace BoundedCounterTest {

  TEST_CLASS(BoundedCounterTest) {
  public:
    // 各テストの開始直前に行う
    TEST_METHOD_INITIALIZE(method_setup) {
      counter_ = new CounterLib::BoundedCounter(0,4);
      Assert::IsNotNull(counter_);
    }
    // 各テストの終了直後に行う
    TEST_METHOD_CLEANUP(method_teardown) {
      delete counter_;
    }

    // 初期状態でのカウント値は2
    TEST_METHOD(constructor) {
      Assert::AreEqual(2, counter_->get());
    }

    // incrementのたびにカウント値が+1される(上限4)
    TEST_METHOD(increment) {
      Assert::AreEqual(2, counter_->get());
      Assert::IsTrue(counter_->can_increment());
      Assert::IsTrue(counter_->can_decrement());
      counter_->increment();
      Assert::AreEqual(3, counter_->get());
      Assert::IsTrue(counter_->can_increment());
      Assert::IsTrue(counter_->can_decrement());
      counter_->increment();
      Assert::AreEqual(4, counter_->get());
      Assert::IsFalse(counter_->can_increment());
      Assert::IsTrue(counter_->can_decrement());
    }

    // decrementのたびにカウント値が-1される
    TEST_METHOD(decrement) {
      Assert::AreEqual(2, counter_->get());
      Assert::IsTrue(counter_->can_increment());
      Assert::IsTrue(counter_->can_decrement());
      counter_->decrement();
      Assert::AreEqual(1, counter_->get());
      Assert::IsTrue(counter_->can_increment());
      Assert::IsTrue(counter_->can_decrement());
      counter_->decrement();
      Assert::AreEqual(0, counter_->get());
      Assert::IsTrue(counter_->can_increment());
      Assert::IsFalse(counter_->can_decrement());
    }
 
    private:
      CounterLib::Counter* counter_;
    };

}
fig-1 テスト結果
fig-1 テスト結果

ViewとModelの分離

 ViewとModel間にViewModelを仲介させることで、一方の変更が他方に及ぼす影響を小さく抑えようという目論見です。特にView(=UI)は使い勝手に大きく関わるため、好き勝手にいじれることが望まれます。現時点のView、すなわちMainPage.xamlのコード・ビハインド:MainPage.xaml.cppを再掲します:

list-5
// MainPage.xaml.cpp (step-0)
// MainPage クラスの実装
...
void CounterApp::MainPage::btnInc_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
  counter_.increment();
  txtCount->Text = counter_.get().ToString();
}

void CounterApp::MainPage::btnDec_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
  counter_.decrement();
  txtCount->Text = counter_.get().ToString();
}

 ご覧のとおり、MainPage(View)がCoutner(Model)を直接駆動しています。この部分は本来UIデザインには関係のない部分です。コード・ビハインドによる実装は極力少なくしたい。データ・バインディングを使ってコード・ビハインド部を減らします。

 このコードでのViewとModelとの関わりは:

  • Model→View:Modelが持つデータ(カウント値)を、Viewにあるコントロール(TextBlock)に表示する。
  • View→model:Viewにあるコントロール(Button)の操作に応じてModelが持つデータ(カウント値)を更新する。

 この2つをViewとModelの仲介役:CounterViewModelにやってもらいます。

次のページ
Model→View

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7130 2013/05/14 14:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー