c++ builder > Observerパターンのテスト実装
15640 ワード
動作確認
C++ Builder XE4
背景
関連 http://qiita.com/7of9/items/358a46b38ebf93c5101a
にてPresentation Domain Separationを教えてもらった。
MVVMなどの1つとしてObserverパターンを使う例があった。
そのObserverパターンをC++ Builderで動くように実装してみた。
注意: 以下のコードは試験実装です。単一責任原則の無視や実装者の理解不足によるまずい実装例が含まれます。
UnitObserver
3つのクラスの混在。
UnitObserver.h
//---------------------------------------------------------------------------
#ifndef UnitObserverH
#define UnitObserverH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <vcl.h>
#include <vector>
class CObserver;
//---------------------------------------------------------------------------
// Subjectクラス
//
class CSubject {
std::vector < class CObserver * > views;
int value;
public:
void __fastcall attach(CObserver *obs);
void __fastcall setVal(int val);
int __fastcall getVal();
void __fastcall notify();
};
//---------------------------------------------------------------------------
// Observerクラス
//
class CObserver {
CSubject *model;
int denom;
protected:
CSubject *getSubject();
int getDivisor();
public:
virtual void __fastcall update() = 0;
__fastcall CObserver(CSubject *mod, int div);
};
//---------------------------------------------------------------------------
// DivObserverクラス
//
class CDivObserver : public CObserver {
public:
__fastcall CDivObserver(CSubject *mod, int div) : CObserver(mod, div){}
void __fastcall update();
};
#endif
UnitObserver.cpp
//---------------------------------------------------------------------------
#pragma hdrstop
#include "UnitObserver.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
int __fastcall CSubject::getVal()
{
return value;
}
void __fastcall CSubject::setVal(int val)
{
value = val;
notify();
}
void __fastcall CSubject::notify()
{
for(int idx=0; idx < views.size(); idx++) {
views[idx]->update();
}
}
void __fastcall CSubject::attach(CObserver *obs)
{
views.push_back(obs);
}
//---------------------------------------------------------------------------
__fastcall CObserver::CObserver(CSubject *mod, int div)
{
model = mod;
denom = div;
model->attach(this);
}
CSubject *CObserver::getSubject()
{
return model;
}
int CObserver::getDivisor()
{
return denom;
}
//---------------------------------------------------------------------------
void __fastcall CDivObserver::update()
{
int v = getSubject()->getVal();
int d = getDivisor();
String msg = String().sprintf(L"%d div %d = %d", v, d, v/d);
OutputDebugString(msg.c_str());
}
Unit1
Unit1.h
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE で管理されるコンポーネント
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "UnitObserver.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
CSubject sbj;
CDivObserver divObs1(&sbj, 3);
CDivObserver divObs2(&sbj, 1);
CDivObserver divObs3(&sbj, 4);
sbj.setVal(20);
}
//---------------------------------------------------------------------------
動作の理解
-
CDivObserver divObs1(&sbj, 3);
などでattach処理(オブザーバへの登録)が行われる - setVal()実行時にnotify(登録しているものへの通知)が実行される
- notify()の中ではそれぞれの登録へのupdate()処理を行う。
C++ Builder向けの最適なコードではないが、だいたいの感じをつかんだ。
エディタだけで実装していくと自分のC++の理解不足を痛感した。
Author And Source
この問題について(c++ builder > Observerパターンのテスト実装), 我々は、より多くの情報をここで見つけました https://qiita.com/7of9/items/8fc59d7814c964d43334著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .