辞書を片手に~PatternResponderの作成(11) | Pythonでなんか作ってみる

辞書を片手に~PatternResponderの作成(11)

機能を追加する前にリファクタリングを片付ける。


・RandomResponderのコンストラクタを整理する


他にも気になったところ(↓)もついかしておく。


・PatternReponderのloadDictionaryPattern()とloadDictionaryResponse()がテストからしか呼ばれていない

・ResonderがloadDictionary()を保持しているのは、しっくりこない

まずは、コンストラクタの方。これは簡単だ。

どこからも呼ばれていないコンストラクタを一旦削除してみればいい。


と思ったが、全部使われている。簡単じゃなかったみたい。


全部、いっぺんに解決しよう。Dictionaryというクラスを導入して、reader,filename,responsesを渡しているのを一掃し、Responder間のコンストラクタの共通化を図る。


まずは、ResponderがDictionaryを保持するように作る。


public class Dictionary {

private Reader reader;

public Dictionary(Reader reader) {
this.reader = reader;
}

public String[] load() {
BufferedReader r = new BufferedReader(reader);
try {
ArrayList response = new ArrayList();
while (true) {
String line = r.readLine();
if (line == null) break;
response.add(line);
}
return (String[])response.toArray(new String[]{});
} catch (IOException e) {
return new String[] {};
}
}
}
 

このクラスをResponder.loadDictionary()で使用するようにする。


public class Responder {
public static String[] loadDictionary(Reader reader) {
Dictionary dictionary = new Dictionary(reader);
return dictionary.load();
}
}


テストを実行する。All Green。大丈夫壊していない。


次にRandomResponderとPatternResponderのコンストラクタにDictionaryを渡せるようにする。


RandomReponderのほうはコンストラクタが一杯あるせいで、どれを修正したらいいのか迷うな。

とりあえず、すべてにつけてみる。

だが、これだと全ての呼び出し元の方にも、Dictionaryを付けなければならない。

まずは、readerのみを置き換えてみる。

既存でReaderを受け取っているコンストラクタをDictionaryを受け取るように変更して、既存でReaderを渡している方はDictionaryを生成して渡すようにする。

最後に、loadDictionary(reader)をdictionary.load()に変更する。


テスト実行。Green。

次はString[]の置き換えをおこなう。DictionaryのコンストラクタでString[]を受け取れるようにする。


public class Dictionary {

private String[] lines = null;

public Dictionary(String[] lines) {
this.lines = lines;
}

public String[] load() {
if (lines != null) return lines;
...

}


nullと比較している部分は気になるが、とりあえずToDoに追加しておいて、今度は、RandomResponderのコンストラクタでString[]を渡しているものをnew Dictionary(String[])を渡すように変更する。

テスト実行。OK。


RandomResponderのコンストラクタからString[]を引数に持つものを削除する。

テスト実行。OK。

最後はfilenameを引数にとるコンストラクタだ。同じようにDictionaryの方にコンストラクタを追加して。

public class Dictionary {

...

public Dictionary(String fileName) {
try {
reader = new FileReader("dics/"+fileName);
} catch (FileNotFoundException e) {
reader = new StringReader("\n");;
}
}
}


同様に呼び出し元を置き換える。

テスト実行。OK。


PatternResponderの方も同様に、Reader→Dictionaryへ置き換える。


最後にResponder.loadDictionary()を削除する。


ResponderTestでコンパイルエラーになるが、このテストケースは既にloadDictionary()のテストしかしていないため、テストケース名をDictionaryTestに変更して、試験内容を変える。


テスト実行。当然、Green。


ToDoリスト

・正規表現を使ってパターンに反応するResponder(以下の仕様を満たす)

・応答例の中に「%match」という文字列があれば、パターンにマッチした文字列と置き換えられる

・RandomResponderのコンストラクタを整理する

・PatternReponderのloadDictionaryPattern()とloadDictionaryResponse()がテストからしか呼ばれていない

・ResonderがloadDictionary()を保持しているのは、しっくりこない

・Dictionaryでコンストラクタで動作を分けているのは美しくない