MVVMって、こんな感じ?
いつものことですが、シリアル通信とかファイル編集とか、ちょっとした実験や雑用をこなすためにチョチョイっとTcl/Tkでスクリプトを書き、使っているうちに「バイナリ通信もできるようにしよう」だの「このファイルフォーマットにも対応しよう」だのと手を加えているうちにスクリプトが肥大化してしまって把握しにくくなってしまいます。
そこで、何かGUIアプリに適した記述方法や動作モデルが無いかとググっていてMVVMなるものを知りました。(すみません、今更でしょうね。本職さんから見れば)
MVVMは「Model」「View」「ViewModel」という3つのブロックに分ける考え方のようです。基本的にはWindows向けソフト開発フレームワークの中の概念らしいのですが、やってみれば何かのヒントになるかも?ということでTcl/Tkでそれっぽく記述してみました。
まずは何も考えず、いつもの調子で記述してみます。
#!/bin/sh
#-*-mode:tcl;tab-width:4;coding:cp932-*-\
exec wish -encoding cp932 "$0" ${1+"$@"}
set WidNumber 0
proc Wid {{parent ""}} {
global WidNumber
if {[string index $parent end] ne "."} {
append parent "."
}
return ${parent}wid[incr WidNumber]
}
proc Sum {} {
global Value
set Value(S) "?"
foreach key {A B} {
if {![string is double -strict $Value($key)]} {
tk_messageBox -icon error -title Error -message "$keyは数値ではありません。"
return
}
}
set Value(S) [expr {$Value(A) + $Value(B)}]
}
set Title(A) "数値A"
set Title(B) "数値B"
set Title(S) "AとBの合計"
set Value(A) 0
set Value(B) 0
set Value(S) "?"
wm title . "Form1"
grid columnconfigure . 1 -weight 1
foreach key {A B} {
set w [list]
lappend w [label [Wid] -textvariable Title($key)]
lappend w [entry [Wid] -textvariable Value($key)]
grid {*}$w -padx 5 -pady 5 -sticky we
grid configure [lindex $w 0] -sticky e
}
set w [list]
lappend w [button [Wid] -textvariable Title(S) -command Sum]
lappend w [entry [Wid] -textvariable Value(S) -state readonly]
grid {*}$w -padx 5 -pady 5 -sticky we
bind [lindex $w 0] <Key-Return> Sum
実行すると、こんな感じ。
これを「MVVMって、こんな感じかな~?」と考えつつ書き直してみました。
MVVMの概要を説明する文章として、
- Viewは、ViewModelに含まれたデータをデータバインディング機構のようなものを通じて自動的に描画するだけ
- ViewModelは、Viewから受け取った入力を適切な形に変換してModelに伝達する
- Modelは、アプリケーションのドメイン(問題領域)を担う
といったものが多かったので、それを尊重して記述してみました。
(TclOOにはまだ慣れていないので、namespaceで記述しました)
#!/bin/sh
#-*-mode:tcl;tab-width:4;coding:cp932-*-\
exec wish -encoding cp932 "$0" ${1+"$@"}
namespace eval ::Model {
proc Sum {a b} {
return [expr {$a + $b}]
}
}
namespace eval ::ViewModel {
variable Title
set Title(A) "数値A"
set Title(B) "数値B"
set Title(S) "AとBの合計"
variable Value
set Value(A) 0
set Value(B) 0
set Value(S) "?"
proc Sum {} {
variable Value
set Value(S) "?"
foreach key {A B} {
if {![string is double -strict $Value($key)]} {
tk_messageBox -icon error -title Error -message "$keyは数値ではありません。"
return
}
}
set Value(S) [::Model::Sum $Value(A) $Value(B)]
}
}
namespace eval ::View {
variable WidNumber 0
proc Wid {{parent ""}} {
variable WidNumber
if {[string index $parent end] ne "."} {
append parent "."
}
return ${parent}wid[incr WidNumber]
}
proc Form1 {} {
wm title . "Form1"
grid columnconfigure . 1 -weight 1
foreach key {A B} {
set w [list]
lappend w [label [Wid] -textvariable ::ViewModel::Title($key)]
lappend w [entry [Wid] -textvariable ::ViewModel::Value($key)]
grid {*}$w -padx 5 -pady 5 -sticky we
grid configure [lindex $w 0] -sticky e
}
set w [list]
lappend w [button [Wid] -textvariable ::ViewModel::Title(S) -command ::ViewModel::Sum]
lappend w [entry [Wid] -textvariable ::ViewModel::Value(S) -state readonly]
grid {*}$w -padx 5 -pady 5 -sticky we
bind [lindex $w 0] <Key-Return> ::ViewModel::Sum
}
}
::View::Form1
要はウィジェットがViewで、-commandに渡す処理と-stateを操作する処理がViewModelで、-commandに渡す処理の汎用サブルーチンがModelってことなのかな。
それであってるなら・・・普通にそうする・・・よねぇ。
なんかちょっと拍子抜け?
Author And Source
この問題について(MVVMって、こんな感じ?), 我々は、より多くの情報をここで見つけました https://qiita.com/qoLop/items/aace081b2e1f70ce32bc著者帰属:元の著者の情報は、元の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 .