モデリングカフェの問題をやってみる:第1回〜第4回
設計とかちゃんと勉強したことないよなと思って最近UMLモデリングの本を読みました。
一通り読んで雰囲気はわかったものの、実際やらないとわからないので適当にモデリングの演習問題を探してみたら非常に良さそうな連載があった。
毎回問題がモデリングの題材が与えられて、「コンセプト」と「クラス図」を回答として出していく形式。「コンセプト」はモデリング対象の捉え方と表現方法を文章にしたものらしい。この説明だけだとよくわからないが、数回実際にやってみて、問題文だけだと情報が完全には与えられていないので、解答者の側で足りない情報を想定する必要があるんだけどその想定を書くのが「コンセプト」だと理解しました。
今日は第1回から第4回までやりましたがけっこう面白い。UMLモデリングの本を読まないままやってたら悲しくて挫折してたと思うので読んでおいてよかった。
第1回:連絡網
問題
ゆうじ君たちは以下のように連絡をとることになっています。 この状況をモデリングしてください。
自分の回答
コンセプト
- 連絡網は生徒が連絡し合うことによって成り立つ
- 生徒は別の生徒から連絡を受け、またさらに別の生徒に連絡をする
- ただし、連絡網の起点となる生徒は連絡を受けることはなく、終点となる生徒は連絡をすることはない
クラス図
回答例・解説を読んだ感想
みんなの回答めちゃくちゃちゃんと考えてあってすごい。自分は連絡手段や連絡内容には完全に考えが抜け落ちていたので反省。そして、コンセプトの書き方がいまいちわからないです。
第2回:社員と辞令
問題
ソフトウェアを受託開発するイラピス株式会社では、2006 年 1 月に以下の辞令が発令されました。
山田さんはジュニアSEに昇格しました
田中さんは技術2部に配属されました
花山さんはミドルSEに昇格しました
社員と辞令の関係をモデリングして下さい。 ただし、職級に関することなど不足する情報は適宜補っていただいて結構です。
自分の回答
コンセプト
- 1つの辞令ではある社員の職位・部署のいずれかもしくは両方が変更される
- 部署の変更には異動や兼務追加・兼務解除があり得る
- 職位は1つの社員につき同時に1つで、部署に関わらないグローバルな概念であるとする
クラス図
回答例・解説を読んだ感想
兼務とかを考慮できたのはよかったと思った。しかし、この時は職位をグローバルなものとして考えたんだけど、よく考えたら普通に部署に職位が紐づいていた方が普通だよなという気分になってきた。例えば、A部の部長とB部のエンジニアを兼務することになるとかがあり得そうなので。
解説の、種類(例えば、「部署」に対する「技術2課」)をサブクラスにするかインスタンスにするかの議論がわかりやすくて、種類ごとに異なる情報や振る舞いを持っていたらサブクラスにすると良いらしい。
回答2の
社員は入社すると格付辞令・配属辞令により、いずれかの職級に格付けされ、いずれかの部門に配属される。
という考えは面白いと思った。こうしてしまうと必ず直前の辞令をみることでその社員の現在の役職と職級がわかる、と。
第3回:部品の構成
問題
型番 D0101 の机の部品構成は以下のとおりです。
机 (D0101) は天板 (T0212) 1つ、脚 (F0132) 4つ、引き出し (H0303) 1つで構成されます
引き出し (H0303) は、箱 (B0505) 2つ、棚 (TA0635) 1つで構成されます
天板 (T0212) や引き出し (H0303) などは他の製品でも利用されます
※ ( ) 内は型番
この例を参考に部品の構成をモデリングして下さい。 不足する情報は適宜補っていただいて結構です。補った情報は、コンセプトに記述してください。
自分の回答
コンセプト
- 型番が付いているものは全て製品として扱う
- 製品は複数の製品から構成されることがある
- 製品と、その製品を構成する製品の関係を製品構成として表す
クラス図
オブジェクト図
これはクラス図を見るだけだとよくわからない系なのでオブジェクト図も作った。
回答例・解説を読んだ感想
これはうまくモデリングできたのでよかった。といっても、直前に読んだUMLモデリングレッスンにほぼそのままの例題が載ってたからなんですが...。「型番が付いているものは全て製品として扱う」としたのはやりすぎ感もあるけど、クラス図としてはシンプルになる。マスター(誰?)の回答では、製品を「単品目」と「ユニット」に分けていてなるほど太郎になった。
第4回:タイムテーブル
問題
2006 年 4 月 7 日(金)にダイエットセミナーが開催されます。 プログラムは次の通りです。 この例を参考に、セミナーのタイムテーブルをモデリングしてください。 不足する情報は適宜補っていただいて結構です。補った情報は、コンセプトに記述してください。
自分の回答
コンセプト
- トラックは会場と1対1でひもづく
- プログラムは食事と講演に分類できる
- 講演には一人以上の講演者がいるものとする
クラス図
回答例・解説を読んだ感想
回答例と違って、自分は講演者が複数の講演をすることもしたらそれを追跡したいと思ってエンティティにした&パネルディスカッションもあるかなと思って講演に複数の講演者をひもづけるようにした。問題文の例に昼食の時間があったので「食事」という完全に謎のクラスを作ってしまったけど「休憩」とかでよかったですね...。マスター(誰?)の回答では休憩を明示的に管理してなかったけど、それは微妙かもと感じた。
カード決済のレシートに印字される6桁の承認番号について
こんにちは、この記事は Kyash Advent Calendar 2019 の17日目です。
以下の2枚のレシートは別の日に同じエクレアを買ったときのものです。エクレアは同じですが決済の方法が違って、左のレシートは現金、右のレシートはKyash Visaカードで決済したものです。
右のKyash Visaカードで決済したレシートにのみ、承認番号と呼ばれる6桁の数字が印字されていますね(赤枠部分)。Kyash Visaカードに限らず、一般にカード決済したレシートにはこの承認番号が印字されます。今日はこの承認番号がどういうもので、どのように使われるのかの一例について書きたいと思います。
オーソリゼーションとクリアリング
まず、カード決済の流れについて簡単に紹介しておきます。カード決済には大きく分けて2つのステップがあります。記事の一番下に図が貼ってありますので、適宜参照ください。
1つ目のオーソリゼーションというステップでは、カード発行会社(カードを"issue"するのでイシュアと呼ばれています)がカード会員が行おうとしている決済を承認もしくは拒否します。会員が加盟店でカードを切ると、オーソリ電文と呼ばれるメッセージが店頭の決済端末からカードの国際ブランド(VisaやMastercardなど)のネットワークを介してイシュアに送られます。電文を受け取ったイシュアは、その内容を見て取引を承認するか拒否するかを決め、結果を加盟店に伝えるため応答電文を送り返します。判断基準としては、会員の決済額が上限額を超えていないかや、カードの有効期限が切れていないかなどが挙げられます。
Kyash Visaカードを使った取引のオーソリゼーションでは、KyashユーザがコンビニやECサイトなどのVisa加盟店でカード決済をすると、Visaのネットワークを介してKyashにオーソリ電文が到着し、Kyashが取引を承認もしくは拒否するという流れになります。ちなみに、クレジットカード決済のオーソリゼーションでは本当に決済可否の判断を行うだけでカード会員の口座残高は動かないのですが、Kyash Visaカードはプリペイドカードなのでオーソリゼーションの段階でユーザの残高から決済額を差し引くという違いがあります。このあたりのプリペイドカード・デビットカード特有の事情については Kyash Visaカードはなぜガソリンスタンドやホテルで使えないのか でも紹介されています。
さて、レシートに印字されている6桁の承認番号に話を戻しますが、これはオーソリゼーションでイシュアが取引を承認したときに発行する番号です。何らかの理由で取引を拒否した場合は承認番号が発行されないので、承認番号はイシュアが取引を承認したことの証拠であると考えることもできます。承認番号がどのように使われるかの話をする前に、カード決済のもう一つのステップを説明しておきます。
カード決済の2つ目のステップはクリアリングと呼ばれ、売上を確定させるためのものです。オーソリゼーションではあくまでイシュアが取引を承認(許可)するだけなので、決済額は確定していませんし、その後決済自体がキャンセルされることもあります。売上を確定させるために、加盟店はオーソリ電文とは別に売上電文と呼ばれるメッセージを送信します。一般に、イシュアに売上電文が到着するのはオーソリ電文が到着した数日後であることが多いです。売上電文が届くとイシュアはクリアリング業務を行うのですが、Kyashではその一環として売上電文を同じ取引のオーソリ電文と紐づけるマッチングという処理を行います。
オーソリ電文と売上電文のマッチング
マッチングでは売上電文とオーソリ電文を紐づけて、売上の確定や Kyashポイント の付与などの処理を行います。また、稀に為替レートの変動などが原因でオーソリ電文と売上電文に記載されている決済額が異なる場合があるのですが、その場合は売上電文の方の決済額が確定した額なので、そちらに合わせてKyash残高の調整を行います。
さて、そもそもどのように売上電文と同じ取引のオーソリ電文を見つけるのかについて説明します。記事の最初に貼ったレシートの例で考えると、同じような時間に同じ店で同じエクレアを購入した人は何人かいるかもしれないので、決済の内容やタイミングだけではマッチングはできません。そこで2つの電文の紐付けに利用されているのが、レシートに印字されている承認番号です。
すでに書いたように、承認番号はオーソリゼーション時にイシュアが取引を承認する際に発行し、加盟店に伝える番号です。実は、クリアリングで加盟店から送られる売上電文には、オーソリゼーション時にイシュアが発行した該当取引の承認番号が含まれているのです。Kyashのデータベースには生成された承認番号がオーソリ電文と紐づいた状態で保存されているので、売上電文に含まれる承認番号から、その取引のオーソリ電文を探すことができます。もちろん、承認番号は6桁しかないため承認番号が同じだからといって同じ決済と判断することはできず、他にもカード番号や決済額などの情報を鑑みてマッチングのロジックを組んでいるのですが、いずれにしても承認番号は同じ取引を探し出す上で重要な役割を果たしています。
まとめ
- カード決済には大まかにオーソリゼーションとクリアリングの2段階がある
- オーソリゼーションでイシュアが許可した取引には承認番号が発行され、レシートに印字される
- Kyashではクリアリングにおいてオーソリ電文と売上電文のマッチングを行なっており、そこで承認番号が使われている
この記事で紹介したのはKyashが行なっている決済業務の中でもほんの一部に関する豆知識のようなものですが、もうすぐ発売の「WEB+DB PRESS Vol.114」では、決済の全体像に加えて、Kyashの裏側のアーキテクチャやインフラ設計、セキュリティについても書かれています。よかったら読んでみてください。
database/sql パッケージでクエリを投げるまでに起こること(1)
よくgoのO/Rマッパーとして gorm を使っているのですが、gormの挙動ではまったりすると内部で使っている標準の database/sql
パッケージの理解が必要になることがあります。これまで直接 database/sql
を使ったことがなかったので、そのクエリを投げるまでの内部動作について調べてみます。今日は、とりあえず sql.Open
するところまで動作を追ったのでそこまで。
サンプルコード
まずは、database/sql
の基本的な使い方として、クエリを投げて複数のレコードを取得する場合にどのようなコードになるかを見てみます。例として、足が6本以上ある動物の一覧が知りたくなった場合のコードを挙げてみます。
package main import ( "database/sql" "fmt" _ "github.com/lib/pq" ) func main() { db, err := sql.Open("postgres", "host=127.0.0.1 port=32768 user=postgres dbname=playground sslmode=disable") if err != nil { panic(err) } defer db.Close() rows, err := db.Query(`SELECT animal, legs FROM animals WHERE legs >= $1`, 6) if err != nil { panic(err) } defer rows.Close() var ( animal string legs int ) for rows.Next() { if err := rows.Scan(&animal, &legs); err != nil { panic(err) } fmt.Printf("%s has %d legs\n", animal, legs) } if rows.Err() != nil { panic(err) } }
postgreSQL を使うことを想定して、ドライバとして github.com/lib/pq
を使っていますが、他のRDBでもimportするドライバを変えれば同じように動くと思います。また、サンプルコードの簡素化のためエラー処理では単に panic
しています。
わざわざ解説するほどのことはないですが、正常に処理が進むと以下のような流れになります。
database/sql
とgithub.com/lib/pq
をimportsql.Open
で*sql.DB
オブジェクトを取得db.Query
でクエリを投げて結果を*sql.Rows
として取得rows.Scan
で結果を変数にマッピングrows.Err
でエラーチェックrows.Close
db.Close
順に、内部でどのような処理がされているのか見ていきましょう。
import
まずはimportからです。
import ( "database/sql" _ "github.com/lib/pq" )
database/sql
パッケージと、ドライバである github.com/lib/pq
パッケージをimportしています。ここで、ドライバの方のimport分にはアンダースコアが使われていますね。このようにimportすることで、pq
パッケージでexportされているものが見えなくなります。パッケージでexportしているオブジェクトが使えなかったらimportする意味がなさそうに見えますが、そんなことはありません。pq
パッケージはimportされる際の副作用として、sql
パッケージへのドライバの登録を行なっています。
具体的に何をやっているのかについては、pq
の init()
関数 を見てみましょう。
func init() { sql.Register("postgres", &Driver{}) }
sql
パッケージの Register
関数に自パッケージの Driver
インスタンスのポインタを渡しています。次に、Register
関数 の方を見てみましょう。
func Register(name string, driver driver.Driver) { driversMu.Lock() defer driversMu.Unlock() if driver == nil { panic("sql: Register driver is nil") } if _, dup := drivers[name]; dup { panic("sql: Register called twice for driver " + name) } drivers[name] = driver }
こちらでは、ドライバを保持するグローバル変数である drivers
に渡されたドライバを登録していることがわかります。この渡されたドライバは、接続の確立やクエリの実行など、今後のいろいろな処理で使われることになります。つまり、ドライバをアンダースコアにエイリアスしてimportし、ドライバから我々が書くコードではなく sql
パッケージに影響を与えることで、必ず sql
パッケージを介してドライバが使われるようになります。これは面白いですね。まあ世の中には他にもっと面白いことがあると思いますが...。
sql.Open
先程登録されたドライバを使って、sql.Open
を行い、データベースの操作に使う *sql.DB
インスタンスを取得します。注意点として、ソースコードのコメント にも書かれている通り、sql.Open
ではデータベースへ接続する下準備をするだけで、接続の確立は行われません。少し直感に反していると思いますが、接続の確立はクエリを投げる時など実際に接続が必要になった時に初めて行われます。コメントの同じ箇所に書かれている通り、sql.Open
に渡した引数で正しく接続ができるのかを確認するには、sql.Ping
を呼ぶ必要があります。ちなみに、gormでは、gorm.Open
の中で sql.Open
した後にちゃんとsql.Ping
が呼ばれていました。
さて、接続する下準備とは具体的にはなんなのかという話ですが、主要な処理は *sql.DB
の connector
プロパティにimportしたドライバから生成した driver.Connector
をセットしていることです。この connector
はのちにデータベースに接続するときに使われます。
まとめ
とりあえず sql.Open
するところまで動作を追ってみましたが、database/sql
とドライバの関係がうまく設計されていて面白かったです。次は db.Query
でレコードを取得して、そのレコードの内容を取り出すところを見ていきます。ちなみに、goの勉強は標準パッケージを読むのが良いと何回か聞いたことがありますが、今回実際に読んでみてたしかにいろいろ勉強になったので、引き続きいろいろ読んでいこうかなという思っています。
「辿り着きたい場所」のない宮森かおりについて
こんにちは、この記事は SHIROBAKO Advent Calendar 2019 の10日目です。どんどんドーナツの方、どーんと行かせていただきます。
SHIROBAKOと「辿り着きたい場所」
SHIROBAKOはどういうアニメか。人によっていろいろな答えがありそうですが、自分は、いろいろな人が仕事を通じて「辿り着きたい場所」に向かっていく物語だと思っています。
SHIROBAKOの前半では「えくそだすっ!」最終話の絵コンテをどうしても進められない木下監督の様子が描かれています。そんな中、監督は舞茸さんとの会話の中で「えくそだすっ!」で自分が本当にやりたかったことに気づき、人が変わったように一気に絵コンテを完成させます。「辿り着きたい場所」という言葉は、その監督の変化を評した本田さんの台詞に登場します。
あおい「絵コンテ、上がりそうでよかったです」
本田「うん、舞茸さん呼んで正解だったよ。辿り着きたい場所がはっきりすると,やるべきことが見えてくるんだな」
「辿り着きたい場所」というのは、たぶん普通に言い換えると「夢」とか「指針」みたいなものの気がしますが、自分の中ではSHIROBAKOを象徴する言葉です。SHIROBAKOでは、全24話の中でいろいろな職種・年齢・能力・性格の人々がそれぞれの辿り着きたい場所に、それぞれのペース・やり方で向かっていきます。辿り着きたい場所を探していたあおいは「えくそだすっ!」「第三飛行少女隊」を通じて自分なりの答えを見つけ、かつて大きな目標を持ちながらも挫折した平岡は再出発の場所を得て、落合さんは野望に向けて淡々とステップアップをしてゆき、本田さんはこれまで向かってきたのとはまったく違う方向に辿り着きたい場所を定めます。丸川社長や河野さんは、「辿り着いた」後も楽しそうに仕事をする大ベテランの姿として描かれているのかもしれません。
さて、そんなアニメであるSHIROBAKOに、辿り着きたい場所がない特異な人物としてあおいの「ねいちゃん」である宮森かおりは登場します。かおりのような人物が登場することも自分がSHIROBAKOを好きな理由の一つなので、今日はそのあたりについて書きたいと思います。
退屈な職場
かおりは7、8話で東京見物にくるという形で突然登場します。かおりが東京に遊びに来たのは、地元でのつまらない仕事から逃れて気晴らしをするためでしょう。
8話で描かれているかおりの職場にあるのは、楽しい仕事や一体感のあるチーム、成長の機会などではなく、どうでもいい合コン、どうでもいいドラマの話、どうでもいい小言を言ってくる先輩です。悲しいですね。
そんな職場にうんざりして東京見物に来たかおりが、りーちゃんとの物見遊山(by あおい)を終えてうに缶をあけながら酒を飲んでいるところに、あおいが夜遅く帰ってきてこんな会話を交わす場面があります。
あおい「うんとね、今日は仕事が予定通り順調に進んで」
かおり「はあ? 予定通りって当たり前でしょ」
あおい「わかってる! 分かってるけどねいちゃん、あのね、予定通りってことはものすっごく、ものすごく珍しいことなんだよ」
かおり「不憫な子...まあ食え」
このとき、かおりはあおいのことを本当に不憫だと感じたんでしょうか。もちろんそれもあるかもしれません。しかし、すべてが予定通り進み、予定通り退屈に終わる毎日を過ごしているかおりにとって、夜遅くに疲弊しつつも充実した様子で帰ってくるあおいは羨ましい存在でもあったのではないかと思います。勝手にうに缶を食べられてしまったことは不憫だと思いますが...。
絵麻とかおり
かおりが登場するSHIROBAKOの7、8話で、メインで描かれているのは実は絵麻です。成長への焦りや将来への不安から「飛ばして」原画を描いてしまった絵麻は、その全てに対して作監の瀬川さんからリテイクを出されてしまいます。その状況を杉江さんや井口さんに助けられながら、絵麻はなんとか乗り越えていきます。かおりが東京見物に来て、気分転換をして地元に帰っていくというのはそれと並行して進むサブストーリーという扱いです。
つまり、7、8話はかおりと絵麻がそれぞれ立ち直って仕事に戻っていく物語だと言えます。しかし、その立ち直り方はまったく対照的ですよね。絵麻は「成長」することで立ち直り、かおりは「気晴らし」することで立ち直っているからです。
絵麻は、杉江さんや井口さんとの関わりを通じて、技術とスピードは全く別の問題であること、好きで始めた仕事でもそのうち新しい目標が必要になること、煮詰まった時は気分転換すること、誰でも最初は真似から始めることを学びます。実力に見合わない仕事の仕方をしてしまいリテイクを出されるという失敗を通じて、作画に関する視座も一段上がっただろうし、つらいときの乗り越え方も覚えたでしょう。この先同じ失敗は繰り返さないだろうし、同じ失敗を繰り返す後輩がいたら導いてあげることもできるはずです。素晴らしいですね。井口さんありがとう。
絵麻「真似していいんですか?」
井口「そうだよ。どんどん見ていいんだよ。それ以外に、どうやってうまくなる? 新人は先輩が描いた動きのパターンをつかんで真似する。自分なりの表現ってのは、それから」
一方のかおりはどうでしょうか。地元での退屈な仕事にうんざりして東京に出てきてやることといえば、りーちゃんとスカイバスに乗って東京見物をする、うに缶を食べながら酒を大量消費する、結婚式に行く人みたいな服を試着する、メイド喫茶に行く...といったいわゆる「気晴らし」ばかりです。ケーキを食べながら次の予定を考える場面では、りーちゃんと以下のような会話がなされます。
かおり「やりたいことないの? あるでしょ? ディナークルーズ行くとか、ニューハーフのショーパブ行くとか」
みどり「やりたいこと...」
かおり「うんうん。夢! 野望!」
みどり「物語が...書きたいです」
りーちゃんの「夢、野望」に対して、かおりが例示する「夢、野望」の気晴らし感がすごすぎる。かおりは、絵麻のように仕事の問題を仕事で成長して解決するのではなく、休日の気晴らしで自分を立て直し、またもとの仕事へと戻っていきます。きっと、かおりは地元に戻ったあとも何かを変える一歩を踏み出すことはないでしょう。退屈な仕事は退屈なまま日々は過ぎていき、耐えられなくなったら休みを取り、また退屈な仕事へ戻っていくというサイクルを繰り返してしまうのではないでしょうか。
いろいろな人生がある
しかし、自分がSHIROBAKOいいなーと思うのは、そんなかおりの生き方がネガティブには描かれていないことです。かおりが地元に帰る朝、あおい宅の玄関先で二人はこんな会話を交わします。
あおい「あ、ねいちゃんさ」
かおり「うん?」
あおい「もういいの? 大丈夫?」
かおり「...まんず、がんばっぺ!」
ここ、とても良いですよね。かおりが地元で行き詰っていることを察しているあおいの気遣いに対して、かおりは前向きに応えます。もちろん、絵麻のように成長して課題をクリアしていければ最高ですが、それと同じくらい、問題は何も解決していなくても、その状況を受け入れ、気分を切り替えて明日も明後日もまたなんとかやっていくだろうかおりも素晴らしいと思います。このとき、あえて普段使わない地元の言葉で返したのは、地元に残り続ける覚悟の表れのようにも聞こえました。作中ではかおりはなぜ地元に残っているのか、仕事以外ではどのような暮らしを送っているかなどはほとんど描かれていませんが、あおいやずかちゃん、りーちゃんとは違う種類の「覚悟と記念と人間の記録」がかおりにもあるのかもしれませんね。
かおりの人生や価値観はメインキャラクターのあおいたちとは正反対です。しかし、冷静に考えるとかおりの方が「普通」の人間じゃないですか? 誰もが仕事を通じてどこかに「辿り着く」わけではないでしょう。むしろそんな人は一握りのはずです。みんなが辿り着く場所に向かっていく作中で、どこにも辿り着かずに仕事をし続ける普通の人間としてかおりを描いているところに、SHIROBAKOのバランスの良さを感じます。
何回見ても面白いSHIROBAKO
自分は今までにSHIROBAKOを何度か見てきています。なんとなくつらいことがあるたびに見ているので、最近この記事を書くために見直していたら妻が「SHIROBAKO見てるけどなんかつらいことでもあったの?」と聞いてきたほどです。
はじめてSHIROBAKOを見たときはかおりの話はたぶんあまり印象に残りませんでした。その頃の自分は研究者を目指していたので、将来に不安を覚えながらも自分の道を進んで行く絵麻に共感を覚えた記憶があります。結局研究者にはなれず、いろいろあって去年、よく知らないけどなんとなくやっていけそうだなと思ったソフトウェアエンジニアとして就職しました。週5日会社に行って、たまに(それこそSHIROBAKOのような)素晴らしい劇的なアニメを見たりして、それはそれとして気晴らしに散歩をしたり、ビールを飲んだり、どうでもよいプログラミングをして、また会社に行っているうちに日々が過ぎていく。なんとなく給料が上がれば良いなとか、プログラミングがうまくなりたいとか曖昧な願望は抱きつつも、辿り着きたい場所があるとはとても言えない。そんな暮らしをしている中でSHIROBAKOを見直して、かおりの姿が自分に重なると同時に、ちゃんとこういう普通の人も描かれていたんだと思って驚いたんですよね。そのあと転職をして、今は仕事も面白くなり、チームで働くことの大切さも少しずつわかってきたので、次にSHIROBAKOを見るときにはまた新たな発見があるかもしれません。
以上です。劇場版楽しみですね。