前回までのあらすじ
- ひとりTDDBCをやります
- お題はt_wadaさんのTDDBCお題スライド P.5
- Githubのこのリポジトリで進めます
- Vol.1
- Vol.2
リファクタリング
def []=(key, value)
@container[key] = value
@contained_key_order << key # ココ!
if @capacity < @container.size # ココ!
shape_container(reduce_contained_keys(1)) # ココ!
end
end
def [](key)
@contained_key_order.tap {|x| x.delete(key) } << key # ココ!
@container[key]
end
def reduce_contained_keys(num)
@contained_key_order.slice!(0, num) # ココ!
end
やっぱり、データを入れる/取り出す時に
どのキーをキャッシュすべき(@containerに残すべき)か、Arrayを操作して管理しているのが気になります。
Arrayの実装に直接依存させないようにしたいので、別途クラスを用意し
それを使ってキーを管理するようにリファクタリングしてみます。
もちろん、今までのテストが全てグリーンな状態でリファクタリングを始めて
終わった後も、そのままテストがオールグリーンになるように進めます!
Historyクラス
データの出し入れの際に使われたキーの履歴を表現します。
record(key)
キーが使われたことを記録します。
keys(capacity)
最近使われたキーをサイズcapacityのArrayで返します。
リファクタリング後
データを入れる
def []=(key, value)
@container[@history.record(key)] = value
shape_container(@history.keys(@capacity))
end
データを取り出す
def [](key)
@container[@history.record(key)]
end
キャッシュのサイズを変更する
def resize(new_capacity)
if new_capacity < @capacity
shape_container(@history.keys(new_capacity))
end
@capacity = new_capacity
end
各メソッドはこのようになりました。
キャッシュとしての振る舞いを担当するLRUCacheと
キーの履歴を担当するHistoryで
いい感じに責務が分担できたかなと思いますが、いかがでしょうか?
Historyクラスのテスト
今回のリファクタリングによって、Historyクラスを新たに作りましたが
Historyクラスに対するユニットテストは追加していません。