Vapor Trail

明るく楽しく元気よく

『Head First オブジェクト指向設計』第3章

第3章要件変更

この章で学ぶこと

要件は常に変化する。設計やアプリケーションがどんなに素晴らしくても、やがてアプリケーションは成長し変更される。この章では、要件変更に対応するための方法を学ぶ。
今回の例では、リモコンを使用して犬用ドアを開閉するようにしていたシステムを、犬の鳴き声に反応して自動でドアが開閉するように要件が変更される。

ソフトウェア分析設計において唯一不変であること = 変更

友好的な顧客が、「正しく動作するアプリケーションを修正する」といったような、狂ったような新しい要件を出すこともある。しかし、良いユースケースがあれば、新しい要件に対応するための変更を迅速に行うことができる。

  1. 要件のよい集合によって、顧客が望む処理をシステムが行うようになる。
  2. システムのユースケースの前ステップを要件が網羅するようになる。
  3. 顧客が指示し忘れたことを発見するために、ユースケースを活用する。

システムに新しい要件または違った動作が必要になるとき、最初にユースケースを更新する。

インパス
1. Fidoが外に出たいと吠える
2. ToddまたはGinaがFidoの鳴き声を聞く
  2.1 鳴き声認識装置が鳴き声を検知する
3. ToddまたはGinaがリモコンのボタンを押す
  3.1 鳴き声認識装置がドアを開くための要求を送信する
4. 犬用ドアが開く
5. Fidoが外に出る
6. Fidoが用を済ます
  6.1 ドアが自動的に閉まる
  6.2 Fidoが中に入りたいと吠える
  6.3 ToddまたはGinaがふたたびFidoの鳴き
    6.3.1 鳴き声認識装置が再び鳴き声を検知する
  6.4 ToddまたはGinaがリモコンのボタンを押す
    6.4.1 鳴き声認識装置がドアを開くための要求を送信する
  6.5 犬用ドアが再び開く
7. Fidoが家の中に戻る
8. ドアが自動的に閉まる

ユースケースがややこしくなってきた。

必要なのはわかりやすいユースケース

ユースケースがわかりにくければ書き直す。重要なのはチーム、顧客に説明して理解できること。

インパス 代替パス
1. Fidoが外に出たいと吠える
2. 鳴き声認識装置が鳴き声を検知する 2.1 ToddまたはGinaがFidoの鳴き声を聞く
3. 鳴き声認識装置がドアを開くための要求を送信する 3.1 ToddまたはGinaがリモコンのボタンを押す
4. 犬用ドアが開く
5. Fidoが外に出る
6. Fidoが用を済ます
  6.1 ドアが自動的に閉まる
  6.2 Fidoが中に入りたいと吠える
  6.3 鳴き声認識装置が再び鳴き声を検知する
  6.4 鳴き声認識装置がドアを開くための要求を送信する
  6.5 犬用ドアが再び開く


6.3.1 ToddまたはGinaがふたたびFidoの鳴き声を聞く
6.4.1 ToddまたはGinaがリモコンのボタンを押す
7. Fidoが家の中に戻る
8. ドアが自動的に閉まる

代替パスとは・・・ ユースケースにおけるオプションまたは代替の手段を提供する、1つまたは複数の追加ステップ。

ユースケースにおいて、最初から最後までステップが揃っているパスのことをシナリオと呼ぶ。今回はメインパスがシナリオ。 ほとんどのユースケースには複数のシナリオが存在するが、その目標はどれも同じ。

ユースケースが変化した場合は、要件を再度見直す。

要件の変化によって、今まで存在にすら気づかなかった、システム上の問題が判明することがある。変更は避けられないことであり、変更に取り組むたびにシステムは改善される。

要件一覧

  1. 犬用ドアの開口部は少なくとも30センチの高さが必要である。
  2. リモコンのボタンを押すと、ドアが閉じていれば開き、開いていれば閉じる。
  3. 開いたドアが閉じられなかった場合、自動的に閉まる。
  4. 鳴き声認識装置は、犬が吠えるのを検知できる。
  5. 鳴き声認識装置は、犬の鳴き声を検知したときに、ドアを開けることができる。

コードの更新

物事はできるだけシンプルに保ってください。意味なく複雑にする必要はありません。

  • 重複は避ける。 コードの重複は、ほとんどどんな場合でも避けるべきである。
    保守する場合は、悪夢であり、通常はシステム設計における問題の現れである

『はじめてのSQL』を読んだ

 SQLは日々の業務でよく使うし、数百万件のデータを扱うようになって、インデックスを計画的に貼って、どういうクエリを発行すればいいのかまで、考えられるようになったが、実は雰囲気でSQLをやっている。このカラムは255文字以上の文字列は保存しないと思うからvarcharにするとか、11桁以上の数値を扱うからbigintにするとかはわかっているつもりというか、エラーが出ないようにそうしているだけであって、細かい型の仕様とかは実はよく知らない。where文で使っているカラムにインデックスを貼ると速くなることは知っているが、なぜ速くなるのかは実は知らない。インデックスを貼ると挿入・更新が遅くなるらしいが、なぜ遅くなるのかは実はよく知らない。そんなこんなでDBちゃんと学ばないといけないなぁと思っていたので、『はじめてのSQL』を読んだ。

・型の理解が深まった。

 Datetimeは"2019-04-01 00:00:00"といった文字列として保存するが、自動で変換されていることを初めて知った。普通に考えれば当たり前のことだが、何も考えずに使用していた。

・インデックスの理解が深まった

 B木インデックスがどのように探索されるのかを知って、複合インデックスでwhereの順番に気をつける理由をやっと理解した。本では姓と名の複合インデックスの例で、姓名を知っていれば電話帳では姓→名の順番で整理されているのですぐ探せるが、名前しか知らないと全項目を調べなければいけないという事が書かれていて、わかりやすかった。

 プログラムを学び始めたときはデータベースはアプリケーションに付随する副次的なものだと考えていたが、データベース設計は、アプリケーションの基礎になるものであって、一番大事なものではないかと最近は考えている。変なテーブル設計にするとアプリケーション側でデータを使用する際に、あれこれJOINしたり加工しなければいけなくなるので、複雑になる上、保存・取得に時間がかかってパフォーマンスが落ちてしまう。インデックスをきちんと貼っていない故のパフォーマンスが出ないとかは、インデックスを付ければいいだけなのでなんとかなるが、わけわかんないテーブルとカラムにしていてパフォーマンスが出ないとかは、もうどうしようもないのではという気持ちになるので、データベース設計もきちんと学びたい。

初めてのSQL

初めてのSQL

 

 

WSLでGoの開発環境を構築

curl -LO https://dl.google.com/go/go1.12.4.linux-amd64.tar.gz  
tar xzf go1.12.4.linux-amd64.tar.gz  
export PATH=$PATH:$HOME/go/bin  
/etc/profileもしくは.profile  
vi ~/.profile  

export PATH=$PATH:$HOME/go/bin  
export GOROOT=$HOME/go  
export GOPATH=$HOME/workspace/go  

GOROOTは
Ubuntu $HOME/go
Cドライブ直下のc/goにシンボリックリンクを貼る。

ln -s /mnt/c/go $HOME  

GOPATHはc/Users/ユーザ名/workspace/go にする。
Ubuntu側に$HOME/workspace(/home/ユーザ名/workspace) ディレクトリを作る
Windows側のホームディレクトリにシンボリックリンクを貼る

ln -s /mnt/c/Users/ユーザ名/go $HOME/workspace  

GOPATHとGOROOTは正直まだよくわかっていない。無駄なことしてるかも。 あと書き方もよくわからない。クラスがないのでmain.goにベタ書きしている感じだが、小さなファイルに切り出していって、それの大きな集合体がmain.goだと考えればいいのか?
gormのソースを見ると、ディレクトリの中にそのままファイルを作っていってる感じだが。