ここでは,SimpleTwitter の DTRAM による仕様記述に関する課題に取り組んでいただきます.
以下に DTRAM で記述された SimpleTwitter のモデルを示します.こちらを適宜参照しながら課題を進めてください.
DTRAM の説明をもう一度ご覧になりたい方はこちらへ(別タブが開きます).
DTRAM では,SimpleTwitter の仕様を以下のような階層化されたリソースで表します.
accounts
:アカウント全体を管理するデータベースaccounts.{accountId}
:accountId
で登録されているアカウントaccounts.{accountId}.name
:accountId
で登録されているアカウントのアカウント名accounts.{accountId}.tweets
:accountId
で登録されているアカウントのツイートリストaccounts.{accountId}.tweets.{tid}
:accountId
で登録されているアカウントのツイートリストの tid
番目のツイートSignup
,accountId
で登録されているアカウントに対してツイートを行うためのイベントチャンネルを Tweet(accountId:Str )
として宣言しています.
Signup
チャンネルでは accounts
リソースが,メッセージ signUp(accountId, name)
を受け取ると, リソースの状態が accountDB
から insert(accountDB, accountId, {"name": name, "tweets": nil})
に変わることを示しています.nil
は空のマップやリストを表しています.
ここで,関数 insert(x, y, z)
は,写像 x
に対し,キー y
と値 z
の対応を追加した結果得られる写像を返す関数です.また {"name": name, "tweets": nil}
は,"name"
と "tweets"
をキーに持つ JSON オブジェクトを表しています.
Tweet(accountId:
チャンネルでは accounts.{accountId}.tweets
リソースがメッセージ tweet(contents)
を受け取ると,
遷移前の状態 tweetList
が append(tweetList, contents)
に変わることを示しています.
ここで,関数 append(x, y)
は,リスト x
に対し,オブジェクト y
を末尾に追加した結果得られるリストを返す関数です.
channel Signup {out accounts(accountDB:Map , signUp(accountId:Str , name:Str )) = insert(accountDB, accountId, {"name": name, "tweets": nil}) }channel Tweet(accountId:Str ) {out accounts.{accountId}.tweets(tweetList:List , tweet(contents:Str )) = append(tweetList, contents) }
先ほどの SimpleTwitter のモデルのリソースとチャンネルを,DTRAM のモデリングツールを使用して可視化したものを以下の図に示します.
この図がモデルの実行に依らない,リソースとチャンネルの関係を表していることに注意して下さい.
図の中央にある accounts
リソースは Signup
チャンネルからアカウントを登録するメッセージを受け取ります.
accounts
リソースの子リソースである,accounts.{accountId}
リソースはアカウントを表しています.
このリソース名に含まれる accountId
はアカウントidを表すパスパラメータで,一意なアカウントの特定を可能にしています.
accounts.{accountId}
リソースの子リソースである accounts.{accountId}.tweets
リソースは accounts.{accountId}
のツイートリストを表しており,
Tweet
チャンネルからツイートを行うメッセージを受け取ります.
ここでは,SimpleTwitter モデルの仮想実行について説明します.この仮想実行で用いるテストケースは次の通りです.
シミュレーションツールを使用すると与えられたモデルに対して,任意の仮想実行を行うことができます.
ここでは上で示したテストケースに従って行った仮想実行を可視化したものを示していきます.まず,システムの初期状態を可視化したものが以下の図です.
初期状態では,accounts
リソースには何のアカウントも登録されていない状態になっています.
次に,accounts
にアカウント名が "Satou" のアカウントを登録するため,accounts
リソースをダブルクリックします.
signUp
というアカウントを登録するためのメッセージを選択します.
signUp
メッセージのシグニチャが表示されます.
accountId
はアカウントid,name
はアカウント名を表します.
ここでは,signUp("@123", "Satou")
を入力します.
次の状態に遷移し,遷移後の状態が表示されます.@123というidを持つアカウント accounts.@123
が accounts
の子リソースとして生成されていることがわかります.
accounts.@123
のツイートリスト accounts.@123.tweets
が 空のリスト(nil),アカウント名 accounts.@123.name
が "Satou" となっていることを確認できます.
次に,登録したアカウント accounts.@123
でツイートを行いたいので,accounts.@123.tweets
リソースをダブルクリックします.
メッセージを選択する画面が同様に表示されますので,ツイートを行う tweet
というメッセージを選択します.
ツイート内容の入力が可能な画面が表示されますので,ここでは tweet("Hello")
と入力して実行します.
次の状態に遷移したため,Hello というツイート内容を持つツイート accounts.@123.tweets.0
が accounts.@123.tweets
の子リソースとしてツイートリストの0番目に生成されていることが確認できました.
ここからが課題です.
本課題ではまず,上記にて説明を行った SimpleTwitter
の仕様に,ある機能を追加した仕様を考えます.
その仕様のモデルを以下に示します.また,そのモデルの仮想実行を可視化したものをその下に示します.これらの図を見ていただいた上で,2つの設問にお答えいただきます.
設問にお答えいただく際は,必ず設問1,設問2の順番でご解答下さい.以下の図と同じものが設問のページにも記載されているのでこのまま設問のページに飛んでいただいてもかまいません.
channel Signup {out accounts(accountDB:Map , signUp(accountId:Str , name:Str )) = insert(accountDB, accountId, {"name": name, "tweets": nil}) }channel Tweet(accountId:Str ) {out accounts.{accountId}.tweets(tweetList:List , tweet(contents:Str )) = append(tweetList, contents) }channel ChangeName(accountId:Str ) {out accounts.{accountId}.name(prevNamr:Str , changeName(name:Str )) = name }
設問1 (別タブが開きます)
設問2 (別タブが開きます)
課題評価アンケート (別タブが開きます)
SimpleTwitter についてのアンケート (別タブが開きます)