Martin Fowler先生の名著『Refactoring』の第2版が、先日発売されました。
Refactoring第2版は、サンプルコードがJavaScriptになっているということもあり、普段JSを書くことが多い自分としては、「Fowler先生はどんなJSを書くのだろう」と気になっていました。
サンプルコードをそのまま写経するのも芸がないので、TypeScriptの学習も兼ね、サンプルコードをTypeScriptに置き換えてやっていくことにします。
JSのコードはTypeScriptのコードとしても有効なので、サボろうと思えばいくらでもサボれるのですが、できるだけ型を付けながらやっていきたいと思います。
なお、本記事のコードは下記リポジトリでも公開しています。
https://github.com/ryo-utsunomiya/refactoring-2nd-ts
何回かに分けて書く予定ですが、まずはセットアップと最初のコード。
セットアップ
開発用ディレクトリを作って、必要そうなものを入れます。
# npm設定を初期化
$ yarn init -y
# tsc(TypeScriptコンパイラ)
$ yarn add -D typescript
# .tsを食わせると即実行できる便利コマンド
$ yarn add -D ts-node
# Node.js用型定義
$ yarn add -D @types/node
package.jsonはこんな感じで
{
"name": "refactoring-2nd-ts",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "tsc",
"watch": "tsc --watch"
},
"devDependencies": {
"@types/node": "^10.12.10",
"ts-node": "^7.0.1",
"typescript": "^3.1.6"
}
}
tsconfig.jsonはこんな感じ(nodeでの実行を想定)
{
"compilerOptions": {
"module": "commonjs",
"target": "es2018",
"sourceMap": true,
"types": ["node"],
"resolveJsonModule": true
},
"exclude": ["node_modules"]
}
できたら適当に実行してみると良いと思います。
$ echo 'console.log("hello")' > hello.ts
$ yarn ts-node hello.ts
...
hello
以上でセットアップ完了。
Starting Point
次に、最初のサンプルコードを動かしてみます。
invoices.jsonとplays.jsonは省略。
最初の時点での、領収書発行関数(statement)は以下のようになっています。
interface Performance {
playID: string;
audience: number;
}
interface Invoice {
customer: string;
performances: Array<Performance>;
}
interface Play {
name: string;
type: string;
}
export function statement(
invoice: Invoice,
plays: { [playID: string]: Play }
): string {
// 関数の中身は書籍と同じなので省略
}
これだけだと動作確認ができないので、動作確認用のファイルを別途用意します。
import { statement } from "./statement";
import * as invoices from "./invoices.json";
import * as plays from "./plays.json";
invoices.forEach(invoice => {
console.log(statement(invoice, plays));
});
実行してみると、以下のように請求書が出力されることがわかります。
$ yarn ts-node index.ts
...
Statement for BigCo
Hamlet: $650.00 (55 seats)
As You Like It: $580.00 (35 seats)
Othello: $500.00 (40 seats)
Amount owed is $1,730.00
You earned 47 credits
ここをStarting Pointにして、リファクタリングを進めていきたいと思います。