つくる: Itemで再設計
第5章のコードを書き換える
第5章のつくる回で書いた検索と集計を、Item を使う形に作り直します。新しい知識は出てきません。
第5章の関数はこうでした。
Go
func searchSummary(names []string, prices []int, categories []string, keyword string) string並びが3つ並んでいます。同じ添字が同じ商品を指すという約束が、コードのどこにも書かれていません。
Item にまとめると、こうなります。
Go
func searchSummary(items []Item, keyword string) string動きを変えずに形を整理するのがリファクタリングです。 ただし、この演習では設計の整理に加えて出力仕様も変えます。第5章の「最多カテゴリ」をやめ、「平均価格」を表示します。前の回と出力は異なりますが、キーワードの完全一致と、空文字なら全件対象というルールは同じです。
平均は合計を件数で割って求めます。価格は0以上を想定し、int 同士の割り算で小数部分を切り捨てます。例えば 10 / 3 は 3 です。件数が0なら割り算をせず 該当なし を返します。この集計・0件処理・表示はひな形に用意済みです。
メソッドに寄せる
判定や計算を Item のメソッドにすると、集計の側が読みやすくなります。
別の題材として、作業が短時間かどうかの判定をメソッドにします。
Go
type Task struct {
Minutes int
}
func (t Task) IsShort(limit int) bool {
return t.Minutes < limit
}
// ここからは main の中
tasks := []Task{{Minutes: 15}, {Minutes: 30}}
for _, task := range tasks {
if !task.IsShort(20) {
continue
}
// ここから先では短時間の作業だけを扱う
}! は真と偽を反転します。continue は今の要素の残りを飛ばします。判定の意味をメソッドにまとめ、呼ぶ側では対象外の要素を飛ばせます。
条件の中身が名前になったぶん、何をしているのか一目で分かります。
|| は「または」です。片方が真なら真になります。例えば isHoliday || hasDayOff は「祝日、または休みを取っている」という条件です。演習では、全件を対象にする条件と、名前が一致する条件を組み合わせます。
何をメソッドにするか
その型のデータだけで判断できる → メソッドにできる
外の情報が要る → 関数のままMatches は Item の名前とキーワードだけで判断できるので、メソッド向きです。一方「一覧の中で最高額か」は他の商品を知る必要があるので、メソッドにはできません。
順番に作る
演習で書くのは、Matches メソッドの定義と、集計の前に対象外を飛ばす処理の2か所です。
採点の呼び出し側は今までの3つの並びを渡します。入口の itemSearch はその形を保ち、内部で []Item を組み立てるコードを用意しています。件数管理、価格の合計、0件処理、平均表示もひな形のまま使ってください。
要件
ItemにMatches(keyword string) boolメソッドを付ける- キーワードが空文字のときは常に true を返す
Matchesを使って絞り込む該当N件 合計M円 平均K円の形を返す- 該当が0件なら
該当なしを返す - 平均は int の割り算で小数部分を切り捨てる
- 3つの並びは同じ長さで、価格は0以上とする