2008年9月12日金曜日

酒飲み父ちゃんのアルコール量チェック – UML でクラス図の概略を作成

酒飲み父ちゃん

わが屋の父は酒飲みだ。大酒飲みというわけではない。酒好きと言った方が正確かな。ばぁちゃんの父ちゃんというのが大酒飲みだったらしく、その息子、つまり、父の伯父に当たる人は、もう臨終間際というとき、親戚中が酒を持ちより、大好きだった酒をたらふく飲んで亡くなったとう話を聞いたことがある。

家の父は、母の目を盗んで酒を飲む。母が所要で出かけるのを見計らっては、コソコソと活動をはじめる。階段を降りる足音。1 階の酒がしまってある扉の開く音がした。そして、しばらくして、風は南風。ベンランダから気持ちのよい風が吹いてくる。そんな中、「ぷ~ん」と香るウイスキーの匂い。あぁ、またやってるなと思い確認に行く。そしらぬ顔でパソコンをしている父。自分も何も気づかないふりをして、部屋の中を見回す。ウイスキーの入っているグラスの気配はない。既に証拠の隠滅を図ったようだ。しかし、さっきよりも強くなるアルコールの匂い。部屋の喚起までは手が回らなかったらしい。部屋へ戻り、携帯へと手をのばす。そう、母へ現状説明をするために…。

 

健康的な飲酒量

「一日に 2 合まで。一週間に 2 日は休肝日を作るのがいい。」と聞いたことがある。多分、父はこれ以上に飲んでいる。「焼酎」を水で薄めコップに 2 杯、それに「ウイスキー」が加わり、そして、「日本酒」もあればそれも飲む。本人は、それほど飲んでないと主張する。「水で薄めているし、量は少ない」と。たしかに、実際にどのくらい飲んでいるのか状況を把握しにくい。果たして、日本酒に換算した場合に何合飲んでいるのか疑問…。

計算しようと思えば、もちろん簡単にアルコールの量を求めることができる。まず、それぞれの酒のアルコール量を求める。

  • 飲んだ量 × アルコールの度数

日本酒 1 合 180 ml 、アルコール度数 15 度として、180 × 0.15 = 27 。これを上記の総量で割れば、日本酒に換算してどれだけ飲んだかわかる。この数値は、直観的にどれくらい飲みすぎているか把握しやすい。

 

知りたいこと

結局、自分が把握したいことは次のことになる。

  1. 想定している酒の上限より、飲みすぎていないか?
  2. 日本酒に換算すると、全部でどのくらい飲んだのか?

 

画面のイメージ

さて、上記をシンプルなアプリにするとしたら、まず、次のような画面が思い浮かぶ。

080912-001

左の画面で、予め、一日に飲んでよいアルコールの量を設定。右の画面では、実際に酒を飲んだときに、「酒の種類」「飲んだ量」「量の単位」を入力する。そして、それに対して上記の「知りたいこと」で書いた結果が表示。

 

酒の制限

もう少し具体的にイメージをしてみる。上記の左の設定画面においては、「アルコール量」を直接指定するのではない。「酒の種類」と、「それをどれだけ飲んでよいか」で指定することができること。このとき、単位も自由に設定。例えば、「日本酒」なら、「2 合」または「360 ml 」と設定することができるようにしたい。

 

飲酒の評価

右の画面は、酒を飲んだ後に、どれだけ酒を飲んだかを記入する。入力すると、左の画面で設定した制限を超えていないかを表示。超えている場合は、「飲みすぎ!」などと表示される。また、飲んだ量が、左で設定した酒と単位から考えて、どのくらい飲んだか表示されること。例えば、「酒の制限」において、「一日、日本酒で 2 合まで」と設定したら、日本酒で単位は「合」で換算した値が表示されること。

 

単位の設定

単位については、自由に設定ができるよう、下図のような設定画面があるとよい。左の列は単位の名前で、右の列はその単位を ml に換算するときに「乗算する値」を記入する。これは、単位が異なってもアルコールの量を比較可能にするためだ。基準となる単位として ml を特別視することにした。 (ただし、はじめからそのように考えていたのではなく、画面の概略を考えながら、また、クラス図を考えながら、そして、実装しながら最終的にそういう形にしようと考えた。)

080912-002

 

酒の設定

おっと、忘れるところだった。 (+_+) 当然ながら、酒を設定する画面も必要。入力する項目は、「種類」と「アルコール度数」。

080912-001

 

クラス図を考える

上記の要求と、画面のイメージよりクラス図の概略を考える。

 

まずは、「酒」クラス。「酒の種類」を設定する画面を想像しながら、必要な情報は「名前」「アルコールの割合」ということがわかる。

080912-002

 

単位

次に「単位」クラス。同じく画面のイメージより、「名前」「単位 ml への変換する場合に乗算する値」の情報が必要であることがわかる。単位を変換するための情報を持っているので、このクラスが単位を変換する操作を持つことにした。

080912-003

 

「単位」がでたので、次は「量」クラス。「量」は「数値」と「単位」クラスへの参照を持つことによって表現する。「量」は、比較可能でなくてはいけないので、ここで比較するためのメソッドを実装。比較の方法は、例えば、「日本酒 1 合」と「ウイスキー 60 ml 」をアルコール量の観点から判別をする。単位が異なっていても比較できるように、先ほど想定した「単位」クラスのメソッドを使い、単位を揃えた後に比較する。

080912-010

 

飲酒

これで「飲酒」クラスを表現できるようになった。「飲酒」は「酒」と「量」への参照を持つことによって表現。このクラスでは「酒」と「量」オブジェクトを使い、「飲んだ量に含まれるアルコールの量」を計算する操作を持つ。

080912-011

 

飲酒リスト

酒を飲むとき、一種類の酒だけを飲むわけではない。「飲酒」の画面を見てもわかるように、複数の酒を飲むことを想定している。その日に飲んだ酒全体でアルコール量がどうであったかを問題にしている。そのため、複数の「飲酒」を保持する「飲酒リスト」なるクラスを想定した。このクラスでは、個々の「飲酒」オブジェクトに問い合わせて、「アルコールの総量」を返す操作を持つ。

080912-012

 

飲酒制約

一番最初に想定した画面「飲酒の制限」。これに対応したクラスが「飲酒制約」。「飲酒」と「量」への参照を持つことによって、その量が一日に飲んでよい酒の量であることを表わす。「飲酒と量」は、それぞれ自分の好きな酒の種類と単位で設定できること。

このクラスは、飲酒制限についての情報を持っているので、「飲みすぎかどうか」を判定することができる。そのため、先ほどの「飲酒リスト」に対して、「飲酒リストが制限を超えていないか?」答えることができる。また、ここで設定した酒の種類と単位より、「その酒の単位当りで、どのくらいの量の酒を飲んだか?」ということにも答えることができるようにする。

080912-013

 

クラス図の全体

以下が全体のクラス図になる。今回、単位の変換を 「ml へと変換する」と固定したので、単位変換の実装がシンプルになりそうだ。ただし、そのような方法とるため、全ての単位において「ml への変換」するための値の設定は、ユーザが責任を負うことになる。実際のところ、それほど単位の数は多くないのでこれで十分に思われた。

080912-014

 

余談

できることなら、例えば以下のように単位の変換規則を設定したら、

  • 「合」から「升」へは 1/10 を掛ける
  • 「合」から「 ml 」へは 180 を掛ける

自動的に、「升」から「 ml 」へと変換できるようになるのが望ましい。つまり、

  • 「升」から「合」へ変換 「 10 を掛ける」
  • 変換規則を組み合わせて、「10 × 180 」を導き、値を適用

という動作が行なわれるとよい。今回は、この実装は後回しに、ユーザの設定に任せることにした。


関連記事