Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って初めたブログ

都道府県のデータを作ってみた話

都道府県」のデータを作りたい。
そんな要望を受けたので、色々と調べてみることにしました。

とはいえ、データがないと何も始まらないので、データを探すことに・・・

取得先候補1: 総務省が出している「全国地方公共団体コードから取得」

www.soumu.go.jp

都道府県・市区町村のデータ、政令指定都市もわかるようになっており、データの形としては○。
しかし、Excelで作られているため、何かしらツールを使って取得しないといけない・・・うーん(= = ;;

取得先候補2: 内閣府が出している「都道府県一覧APIから取得」

opendata.resas-portal.go.jp

APIなので取得は簡単◎。これを使えば楽じゃないかーと思ったが・・・
データが古く、最新のデータが入っていない(= = ;; うーん

取得先候補3: 国土交通省が出している「都道府県コード一覧から取得」

www.land.mlit.go.jp

これもAPI。最新のデータも入っているように見える。
しかし、更新履歴等が無く、APIがいつ更新されるかも不明なので、継続的に使用するのはちょっと怖い・・・うーん(= = ;; うーん

結果: データ取得先候補1を選定

Excelで作られてはいるが、データとしては揃っているので、これを使うことにしました。
Excelから抽出できるツールは、なんちゃってTypeScriptで作ります。
出力結果は、jsonのようでjsonじゃないファイルで作ります。

import * as XLSX from "xlsx";
import { createWriteStream } from 'fs'

// 読み込み用Excel
let workBook = XLSX.readFile('./assets/000618153.xls')

const sheetList = workBook.SheetNames
const sheet1    = workBook.Sheets[sheetList[0]]
const sheet2    = workBook.Sheets[sheetList[1]]

interface JsonSheet {
  '団体コード': string,
  '都道府県名\n(漢字)': string,
  '市区町村名\n(漢字)': string,
  '都道府県名\n(カナ)': string,
  '市区町村名\n(カナ)': string
}

const jsonSheet1: JsonSheet[] = XLSX.utils.sheet_to_json(sheet1)
// 政令指定都市Sheetは、ヘッダーが無いため配列で格納する
const arraySheet2: string[] = XLSX.utils.sheet_to_json(sheet2, {header: 1})

// 政令指定都市Sheetの団体コードは、StringとNumber型が混在しているため、Stringに統一させる
const arrayStringUnifySheet2 = arraySheet2.map(x => typeof x[0] === 'number' ? [String(x[0]), x[1], x[2]] : x)

const prefectures = jsonSheet1.filter(cel => !cel['市区町村名\n(漢字)'] && !cel['市区町村名\n(カナ)'])
const cities = jsonSheet1.filter(cel => cel['市区町村名\n(漢字)'] && cel['市区町村名\n(カナ)'])

// 書き込み用Jsonファイル
const src = createWriteStream('./assets/prefMaster.json')

prefectures.forEach( cel => {
  let prefCode = cel['団体コード'].slice(0, 2)

  let city = cities.filter(cel => prefCode === cel['団体コード'].slice(0, 2))
  let ordinanceDesignatedCity = arrayStringUnifySheet2.filter(cel => cel[0].slice(3, 5) !== '00' ? prefCode === cel[0].slice(0, 2) : false)

  city.forEach(x => {
    src.write(`{ "prefCode": "${prefCode}", "prefName": "${cel['都道府県名\n(漢字)']}", \
"cityCode": "${x['団体コード'].slice(0, 5)}", "cityName": "${x['市区町村名\n(漢字)']}" }`)
    src.write('\n')
  })
  if (ordinanceDesignatedCity) {
    ordinanceDesignatedCity.forEach(x => {
      src.write(`{ "prefCode": "${prefCode}", "prefName": "${cel['都道府県名\n(漢字)']}", \
"cityCode": "${x[0].slice(0, 5)}", "cityName": "${x[1]}" }`)
      src.write('\n')
    })
  }
})

よし!では、出力結果を見てみよう!

{ "prefCode": "01", "prefName": "北海道", "cityCode": "01100", "cityName": "札幌市" }
{ "prefCode": "01", "prefName": "北海道", "cityCode": "01202", "cityName": "函館市" }
{ "prefCode": "01", "prefName": "北海道", "cityCode": "01203", "cityName": "小樽市" }
{ "prefCode": "01", "prefName": "北海道", "cityCode": "01204", "cityName": "旭川市" }
// ・・・省略・・・
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47362", "cityName": "八重瀬町" }
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47375", "cityName": "多良間村" }
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47381", "cityName": "竹富町" }
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47382", "cityName": "与那国町" }

できたー。

まとめ

都道府県のデータを取得するのって、簡単だろう」と思ったら、意外とちゃんとしたデータって落ちていないものですね。
皆さんどうやって作っているのだろうか・・・

新年早々Vue.jsのSPA/SSR/SSGを整理してみた話

はじめに

明けまして、おめでとうございます。
まだまだコロナで苦しい日々が続きますが、皆様頑張ってのりきりましょう(T T;;

さて、新年早々(ホントは年末から)、Vue.jsを使ってSSR、SSGで作るのってどうするんだ?と思って、色々調べてたので、調べたことを纏めて書いておこうと思います。
SPA、SSRの定義から曖昧な人なので、定義から確認していくこと・・・

SPA vs SSR

  • SPA(Single Page Application) ・・・ 1つのHTML内でコンテンツのみを切り替えるアプリケーションのこと。
  • SSR(erevr Side Rendering) ・・・ コンテンツ毎にサーバー側でHTMLを生成してブラウザに返す仕組みのこと。

SPAの場合、コンテンツの切り替えをブラウザ側のJavaScriptを使って行うため、必ずしもサーバーが必要というわけではありません。
SSRの場合、HTMLをサーバーサイドで生成する必要があるため、必ずサーバーが必要になってきます。

f:id:special-moucom:20210103001142p:plain

どうしてSSRが必要なのか?

SSRを使う理由の1つとして「SEO」が上げられます。

クローラーは、完全に描画されたページ(HTML)を直接解析しています。
そのため、SPAのようなJavaScriptを使ってコンテンツを切り替えているようなページ(HTML)は、クローラー側で正しくページを評価できない(正確には、JavaScriptを正しく実行して、切り替えたコンテンツを解析してくれているかわからない)という問題があります。

とはいえ、昨今ではクローラーの機能も向上しており、今後はSPAで作られたページ(HTML)でも正しく評価されるようになると思われます。
それまでは、「SEO」を重視するのであればSSRが必要となります。

もう1つの理由は、JavaScriptのダウンロード時間です。

SPAは、JavaScriptを使ってコンテンツを切り替えるため、JavaScriptの容量が大きくなりがちです。
そうなると、JavaScriptのダウンロードに時間が掛かり、クローラーの評価を落とす要因になります。

こういった観点からもSSRが必要になってくるケースは多いと思われます。

SSR vs SSG(プリレンダリング(事前描画))

Vue.jsでは、「SEO」目的でSSRするなら、SSG(プリレンダリング(事前描画))がオススメですよ。と書いてある。

SSR vs プリレンダリング (事前描画)

もしあなたが、幾つかのマーケティングのページの SEO を向上させるためだけに SSR を調べているとしたら (たとえば /, /about, /contact など)、代わりに プリレンダリング (事前描画) を使用することをオススメします。 
HTML を急いでコンパイルするために Web サーバーを使用するのではなく、プリレンダリングは、ビルド時に特定のルートに対して静的な HTML ファイルを生成します。
利点はプリレンダリングを設定する方が遥かに簡単で、フロントエンドを完全に静的なサイトとして保つことができることです。

プリレンダリングとは事前描画のことで、コンテンツ毎に必要なHTMLを事前に作成しておく仕組みのこと。つまり、Static Site Generator(SSG)。
JavaScriptを使ってコンテンツを切り替えるが、切り替えたコンテンツは事前に作成しておいたHTMLを表示しようというもの。
そのため、必ずしもサーバーが必要というわけではありません。

f:id:special-moucom:20210103001152p:plain

HTMLは事前に作成しているため、クローラーからも正しく評価されるし、JavaScriptの容量も大きくなり辛いので、ちょうどSPAとSSRの良いとこ取りみたいな感じですね。

SSRを再評価してみる

じゃあ、これからはSSRではなく、全部プリレンダリングで作れば良いじゃん・・・
とは、大きな声では言えませんがクローラーの機能も向上しているのでSSRのメリットが少なくなっているのは事実です。

SSRは、SPAやプリレンダリングでは得られない以下のようなメリットもあるので、要件によってどれを選択するかを決めたほうがよさそうです。

  • クライアントサイドでAPIを実行してHTMLを生成するよりも、サーバーサイドでAPIを実行してHTMLを生成して表示した方が、クローラー側で正しくページを評価してくれる。
  • コンテンツ表示までの時間を短縮できる。
  • コンテンツのアップロードの度にビルドをする必要がないので、大量ページを必要とする場合にむいている。

また、どうせ裏の仕組み(API等)を作る必要があるのなら、いっそのことSSRにするという選択肢もありますね。
その裏の仕組みもJavaScriptを使って作るアイソモーフィック(Isomorphic)ユニバーサル(Universal)といった単語も最近では良く聞きます。

アイソモーフィックJavaScript

アイソモーフィック(Isomorphic)とは、「同型の」という意味で、クライアントサイドとサーバサイドを同じ言語(JavaScript)を使って実装して、コードの共有を行うこと。 つまり、「JavaScriptを使ってSSRやりましょう」イコール「アイソモーフィックJavaScriptでやりましょう」ということ。

ユニバーサルJavaScript

ユニバーサル(Universal)とは、「全般の」という意味で、クライアントサイドとサーバサイドだけでなく、モバイル端末や組み込みデバイス上まで同じ言語(JavaScript)を使って実装して、コードの共有を行うこと。 アイソモーフィックJavaScriptの考え方をさらに広げようといった意味が込められている。

上記のように、SSRは「SSRで作るメリット」があるので、ケースバイケースでSPA、SSR、SSGを選択しましょう。

最後に

去年末のAdvカレンダーで、Vue.jsのSSGフレームワークGridsomeについて調べたことを書きました。

qiita.com

データソースをGraphQLを使ってアクセスできる面白いフレームワークなので、興味のある方は是非読んでみてください。

さて、個人的な観点で、SPA、SSR、SSGについて、整理してみました。
タイトルに「Vue.jsの」と書きましたが、「Vue.js」の内容はあまり含んでいなかったですね。(Vue.jsのWebサイトから抜粋してきたものが多いですが・・・)

2020年を振り返るのと2021年の抱負について

2020年を振り返りたいと思います。 コロナの影響で生活スタイルに大きな変化があり、そのあたりも踏まえて書いていきたいと思うので、「仕事・プライベート」と(いつもの)「技術」の2つの角度から、2020年を振り返ります。

2020年はどんな年だった?

仕事・プライベート

まずは、2020年の「仕事・プライベート」面から見ていきます。

在宅ワークがメインになった

コロナの影響により、会社のオフィスが縮小して、在宅ワークがメインになりました。会社への出勤時間が無くなったので、その時間は家事・育児に労力を回せるようになりました。 これには、個人的に良い点と悪い点がありました。箇条書きにすると以下の通り。

  • 良い点

    • 家族と一緒にいられる時間が増えた
    • 家事(掃除、洗濯)が捗る
  • 悪い点

    • 子供が保育園から帰ってくると仕事にならない
    • 仕事のオン・オフの切り替えが曖昧
    • (定時以降に行われる)カンファレンスやイベントに参加できない

このあたり、小さな子供持つエンジニアの方々のブログを拝見すると、皆さん同じような意見を持たれる方が多いようですね。
特に辛いのが「子供が保育園から帰ってくると仕事にならない」ところです。
私の場合、仕事で残業が発生するときは、仕事を一旦定時で切り上げ、続きを子供が寝静まった後にします。
これが続くと、時間があれば会社のPC開く習慣ができ、「仕事のオン・オフの切り替えが曖昧」になってしまうという問題があります。

私自身、在宅ワークに憧れを持っていましたが、いざ実践するとなるとなかなか上手くいかないもので、現在進行中で苦労しています。

健康に気を使うようになった

在宅ワークになってから、健康に気を使うようになりました。在宅ワークになってから4、5ヵ月たったある日、体重計にのってみると体重が4、5キロ増えていることに気づき、驚きました。

スマートウォッチを購入して、毎日の歩数を計測してみると、通勤していたときは10000歩以上歩いていましたが、在宅ワークのときは、4000歩以下であることがわかりました。

改めて運動不足であることがわかり、毎日4000歩は必ず歩く様、目標設定することにしました。

※購入したスマートウォッチは、以下。

また、家の椅子がそんなに良いものでは無かったために、腰と首を痛めました。 あまりにも痛かったので、整体(カラダファクトリー)で見てもらうと、いかに自分の姿勢が悪かったのかを指摘されました。

以降、デスク周りのレイアウト(モニターの位置)を調整したり、改めて椅子も購入することにしました。

※購入した椅子は、以下

ブログの更新が止まった

在宅ワークになってから、ブログの更新が停止しました。
理由は2つあり、1つは会社内でブログのようなものを書くようになったこと。もう1つは、私は普段、通勤時間を使ってブログの記事を考えたりしていたのですが、その時間が無くなったことです。

アウトプットが減ったというわけではないのですが、外へのアウトプットは減っているので、このあたりは今後改善を目指したいと考えています。

技術

続いて、2020年の「技術」面を見ていきます。

Laravelに挑戦できた

仕事でLaravelを扱うプロジェクトに参加して、Laravelに触れる機会を頂きました。 その結果、Laravelへの理解がすごく深まった気がしています。

私は以前から上司にLaravelに触れるお仕事がしたいと手を上げていました。 その結果、上司から「こんな仕事もあるけど・・・どう?」みたいな形で、お話があり、すんなりとプロジェクトへ参画することができました。

こういったこともあるので、普段から自分のやりたいことに対して声を上げておくことは、重要だと改めて思いました。

AWSの資格を再取得できた

年初の話ですが、AWSソリューションアーキテクト(アソシエイト)、AWSデベロッパー(アソシエイト)の2つを無事、獲得することができました。 このあたりは、以下記事に纏めています。

kodak.hatenablog.com

WordPressのカスタムブロックを作った

仕事でWordPressを扱う案件で、カスタムブロックを作るお仕事を頂きました。 当時、Gutenbergの情報は少なかったので、作るのに大変苦労しましたが、Reactの理解も深まり、なによりPHPの世界からいきなりJavaScriptの世界に飛び込んだこともあって、作っていてとても楽しかったです。

qiita.com

オブジェクト指向デザインパターンを理解できた

改めて、オブジェクト指向デザインパターンリファクタリングを理解しました。 今までは「概念」だけはわかる状態で置いていたもの達を、ちゃんとした本を読むことで、「概念」から「理解」へ進めることができました。

github.com

kodak.hatenablog.com

2021年はどんな年にしたいか?

仕事・プライベート

さて、続いて2021年をどんな年にしていきたいか?「仕事・プライベート」面から見ていきます。

断捨離とスタイリッシュな仕事空間作り

家にいる時間が増えたので、自分の居場所を快適にしていきたいと思います。 在宅になって、いつでも配達を受け取れるようになったので、捨てようと思っていたPCや粗大ゴミが一気に片付きます。メルカリもやり易くなりました。 これによってストレスも解消されるので、断捨離とスタイリッシュな仕事空間作りを目指したいと思います!

老後について考える

35を過ぎたので、そろそろ老後について考えなくてはならない歳・・・ 「老後2000万円問題」なんてものもありましたね。老後に向けた貯蓄について、少しづつですが考えていきたいと思います。

ブログの継続

継続って難しいですよね。はい。私が一番苦手な分野です。 子供にも言っています。「いきなりはできないよ。何事も、ちょっとづつやることで、できるようになるんだよ。だから、毎日ちょっとづつやろうね。」と・・・ そのちょっとづつが難しいんですよね。 子供に言っているだけに、自分がお手本にならなくてはいけませんね

技術

最後に、2021年をどんな年にしていきたいか?「技術」面を見ていきます。

JavaScriptを得意な言語にする

うちの会社では最近、JavaScriptやTypeScriptができる人を増やしていこう。という目標を立てています。 バックエンドとフロントエンド共に、JavaScriptやTypeScriptでできていれば、コードの流用やフロントエンドの人でもバックエンドのコードが読める等、いろいろとメリットが多いからだそうです。 いわゆる、ユニバーサルやアイソモーフィック的な考え方ですね。

これには、私なりに色々と思うところはありますが、JavaScriptとTypeScriptは理解していないと積むことが多いので、まずは、ちょっとデキルからちゃんとデキルくらいにはなっていきたいと思います。

テストコードが書けるようになる

プログラムを作り終えた後に、テストコードを書くのにはだいぶ慣れてきた気がします。ですが、プログラムを作る時にテストコードを書く(つまり、テスト駆動開発)は、まだできていません。
なので、来年はテストコードをたくさん書いて、テスト駆動開発ができるようになる!そんな年にしたいと思います。

まとめ

2020年はコロナの影響で、大きく色々なことが変化を受けた年でした。 2021年はその変化の対応していく・・・そんな年になりそうです。(= = ;;

Cloud Runについて調べてみた話

AWSだけでなく、GCPについても知識を深めていこうと思い、最近流行りのCloud Runについて調べたことを書いていきます。

Cloud Runとは?

GCPが提供しているサーバレスプラットフォームは以下3つあるが、その内の1つ。

  • Cloud Functions
  • App Engine
  • Cloud Run <- コレ!

中でもCloud Run自分で作成したDockerコンテナをサーバーレス環境で実行できるという特徴を持つ。

GCPが提供しているサーバレスプラットフォームの選び方(使い分け)

GCPのドキュメントに書いてあったので、こちらを転機。
https://cloud.google.com/serverless-options/?hl=ja

Dockerコンテナを動かすという特徴から、好きな言語とライブラリを使って開発したい場合に選ばれることが多い。
それだけでなく、規模や開発容易性からも選ばれることが多そう。。。

料金

https://cloud.google.com/run/pricing?hl=ja

上記に書いていますが、イマイチピンときません。私はお金にうるs(ry
簡単に式にすると、以下になる模様。

  • (呼び出し回数 * Requestの時間) * スペック(CPU/メモリ)

以下の料金シミュレーションをしてみると、(デフォルトスペックなら)1 Request(10秒)を100万回実行しても0円なので、結構リーズナブルなんではないかと・・・ (多分、無料枠分で結構遊べるので、個人開発や個人サイトで運用する分なら、ほぼ無料だと思われる)

https://cloud.google.com/products/calculator?hl=ja

使い方

以下ご参照。
https://cloud.google.com/run/docs/quickstarts/build-and-deploy?hl=ja

試しに実施してみましたが、使用するのはCloud Runだけかと思いきや、他にも以下サービスも使いました。

  • Cloud Build ・・・ コンテナのビルドはココで行う。
  • Container Registry ・・・ コンテナのビルド後のイメージをココで管理する。(イメージファイルはCloud Storageに格納)
  • Cloud Storage ・・・ コンテナのビルド前、ビルド後のイメージファイルはココに格納される。
  • Cloud IAM ・・・ Cloud Runの実行権限等の管理はココ。

Cloud Runへのデプロイまでに、以下ステップを踏む模様。

  • Step.1: Cloud Storageにビルド前ファイルを配置
  • Step.2: Cloud Storageに配置したビルド前ファイルを使用して、Cloud Buildでビルド
  • Step.3: Cloud BuildでビルドしたイメージはContainer Registry管理。ビルド後のイメージファイルはCloud Storageに配置
  • Step.4: Container Registry(ビルドしたイメージ)からCloud Runで起動。権限周りはCloud IAMを使用

Cloud Runへデプロイは直接ではなく、Container Registryから行う流れですね。
このあたりはAWSも同じですね。

上記で記載した料金についても、上記4つサービスすべてに料金(従量課金)が掛かってくるので注意!
とはいえ、無料枠もあるので微々たるものだと思います。
1回しかデプロイしないのであればCloud StorageContainer Registryにあるビルド前ファイルとイメージファイルは削除して良いかもしれません。
(デプロイすればするほどCloud Storageに履歴ファイルが溜まっていくので、このあたりも定期的な削除が必要です)

認証・公開制限

Cloud Runでは、今のところCloud IAMを利用した認証・公開制限しかできません。
つまり、IP制限Basicを利用した制限コンテナ内で行うかCloud Endpoints等の他サービスを利用する必要があり、工夫が必要です。

CDN配信

Firebase Hostingと連携すれば、GCPサービス内で完結できます。

https://firebase.google.com/docs/hosting/cloud-run?hl=ja

まとめ

Cloud Runを使用するにあたり、Cloud Runだけでなく他サービスの理解も必要だと感じました。
とくにCloud IAMの理解は必須。Cloud Endpointsも使えるようになっておくと、さらに便利そうです。
というわけで、引き続き他サービスについても勉強していきたいと思います。(= =)>

『リファクタリング 既存のコードを安全に改善する(第2版)』の感想

著者:MartinFowlerさんの本『リファクタリング 既存のコードを安全に改善する(第2版)』を読んだので、その感想エントリーを書いていきたいと思います。

本書の第1版は「Java」で書かれていたのですが、第2版は「JavaScript」で書かれているので、フロントエンドの方でも読みやすくなっていると思います。
*とはいえ、「JavaScript」で説明できない部分(アクセス修飾子の表現等)は、「Java」で書かれているので注意してください。

本書のChapterと感想

本書のChapterは以下の通り、Chapterごとに感想を書いていきます。

Chap.1 リファクタリング-最初の例

サンプルコード(劇団員を派遣して演劇のパフォーマンスを行う会社を想定して、演じた劇に対する請求書を作成するコード)を例に、リファクタリングしていく一連の流れが書かれています。
このChapterを読むだけで、コードをリファクタリングしていく流れを体験できると思います。

私も本書を読むまで知らなかったのですが「いきなり目的に向かってリファクタリングをしても良いコード」と「いきなり目的に向かってリファクタリングをしてはいけないコード」があります。
たとえば、以下のようなサンプルコードがあり、関数名をinOldEngland(c)inNewEngland(c)に変更したいとします。

const newEnglanders = someCustomer.filter(c => inOldEngland(c));

function inOldEngland(aCustomer) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(aCustomer.address.state);
}

関数名をただ変更するだけなので、直接関数名を変更したくなりますが・・・
ちょっと立ち止まって考えてみましょう!

関数名を変更すると、呼び出し側の関数名も変更する必要があります。
呼び出し側が1つしかないのであれば問題ありませんが、呼び出し側が複数ある場合、いきなり関数名を変更すると変更漏れが発生するかもしれません。
また、関数名が変わることで「引数の見直し」もしたくなるかもしれません。

このような場合、関数名変更後の関数を仮実装(inNewEngland(c)を仮実装)して移行することを考えます。

// Step.1
// 関数名を`inNewEngland(c)`に変更
const newEnglanders = someCustomer.filter(c => inNewEngland(c));

// 関数`inNewEngland`を仮実装する
function inNewEngland(aCustomer) {
  return inOldEngland(aCustomer);
}

function inOldEngland(aCustomer) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(aCustomer.address.state);
}

引数も見直します。
こちらも段階的に変更します。

// Step.2
const newEnglanders = someCustomer.filter(c => inNewEngland(c));

function inNewEngland(aCustomer) {
  return inOldEngland(aCustomer.address.state);
}

// 引数を`stateCode`に変更。呼び出し側(仮実装側)の引数を変更します。
function inOldEngland(stateCode) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(stateCode);
}
// Step.3
const newEnglanders = someCustomer.filter(c => inNewEngland(c.address.state));

// 引数を`stateCode`に変更。呼び出し側(実装側)の引数を変更します。
function inNewEngland(stateCode) {
  return inOldEngland(stateCode);
}

function inOldEngland(stateCode) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(stateCode);
}

上記コードで、ちゃんとテストをして問題ないことを確認してから、仮実装した関数は削除して、以下コードに変更します。

// Step.4
const newEnglanders = someCustomer.filter(c => inNewEngland(c.address.state));

function inNewEngland(stateCode) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(stateCode);
}

上記は遠回りなリファクタリングの方法です。
「テストをしていれば大丈夫!」と考える人もいると思いますが、「テストに責務を持たせすぎないこと!」というのも、本書では書かれています。
リファクタリングは小さな変更の積み重ねであること!」これが本書でMartinFowlerさんの言いたかった事の1つです。

Chap.2 リファクタリングの原則

リファクタリングの定義、リファクタリングを行う理由、リファクタリングはいつすべき?、問題点など・・・
リファクタリングの原則について書かれています。
やっぱり「IDEを使うのがいいよね」的な話も書かれていました。

Chap.3 コードの不吉な臭い

いわゆるリファクタリングすべき場所を解説している。
このあたりは「不吉な臭い」等でググると書いている記事が多くでてくる。
とはいえ、第1版と第2版ではいくつか追加・削除されたものもあるので注意。

devtab.jp

Chap.4 テストの構築

リファクタリングにはテストが欠かせない・・・というお話。
最近は、開発者にとってテストは関心事の1つになってきているとも書いてありましたね。テストやりましょう・・・・m( )m

Chap.5 カタログの紹介

ここから以下のChapterすべてリファクタリングテクニックのお話。 「うーん、書いてみないとわからんなぁ・・・」という箇所は、雑に写経しながら理解しました。

Chap.6 リファクタリングはじめの一歩

関数と変数に着目したリファクタリングのテクニック集。
- 関数は一画面に収まらなければ、ロジックを詰め込みすぎだと考える - 2回以上使われるコードはそれ自体を関数にすべき! - パラメーターが多すぎるならオブジェクトごと渡す!

などなど、いわゆるリファクタリングの王道パターンに対するテクニック集が記載されていました。

Chap.7 カプセル化

クラスに着目したリファクタリングのテクニック集。
私はあまり意識していなかったのですが、関数からコレクションを返す時は、コピーか読み取り専用にするのが良いとされていますね。
昨今では、このあたりもパフォーマンス的に問題になることは少ないとも書かれていました。
前のChapterでも書かれていましたが「変数・関数に名前を付ける -> 名前以上のことをする処理の場合はクラス化する」これを守っていればよさそうです。
委譲の隠蔽仲介人の除去は使い方が難しいテクニック(= o = ;;)

Chap.8 特性の移動

クラスや関数のロジックの移動に着目したテクニック集。
オブジェクト指向の大原則「データ構造処理を分離しよう」にしたがってリファクタリング(移動)しましょう!という感じですね。
ループの分離なんかで書かれている「1回のループで処理したいという理由だけで、2つの異なる処理を同時に行っているループをよくみる。」というコメントは、イタタタ・・・・

Chap.9 データの再編成

変数、フィールド名やそれ自体の置き換えや変更に着目したテクニック集。
フレッド・ブルックスの名言「フローチャートを見せてくれても、テーブルを隠されたら煙に巻かれたままだろう。テーブルを見せてくれれば通常フローチャートは要らない。それだけですぐわかる」 それだけ、名前って大切なんですね。ところで、フレッド・ブルックスって誰?(= = ;;)注)すごい人です
「変更可能なデータは、ソフトウェアにおける問題の発生源となる。」とのことですね。
話は変わりますが、TypeScriptreadonly修飾子がありますが、これが使えるだけで結構変わりそうです。

Chap.10 条件記述の単純化

条件分岐に着目したテクニック集。
ポリモーフィズムによる条件記述の置き換えは何を言っているのかさっぱりだったので、写経多め・・・
条件分岐にアサーションを入れてコメント代わりに使う方法があった。
Fowlerさんはセルフテストと呼んでいるそうですが、こんな使い方をするのもおもしろいですよね。

Chap.11 APIリファクタリング

関数、関数の引数などの呼び出し側に着目したテクニック集。
個人的にでるかな〜?と思っていた、setterの削除はここで登場。
「関数に渡す引数が、その関数に相応しいかを考えよう」をFowlerさんは責務という言葉を使って「債務が関数側に相応しいかを考えよう」と言っていました。
ファクトリ関数によるコンストラクターの置き換えで、コンストラクターの制限について書いていましたが、正直そんな事まで考えたこともありませんでした。m( )m

Chap.12 継承の取り扱い

最後は継承に着目したテクニック集。
委譲継承を同列で考えたことなんてありませんでした。m( )m
委譲によるサブクラスの置き換え委譲によるスーパークラスの置き換えはぜったい難しい。。。

さいごに

というわけで、雑な写経をしつつ、本を読み進めてみました。
大切なのはChap.3 コードの不吉な臭いを覚えること。そして、それに着目して怪しいコードはリファクタリングしていくこと。
リファクタリングはいつすべきなのか?」という問に対しても、Fowlerさんは「常に」と回答しています。
テクニックだけではなく、リファクタリングは身近なものでなくてはならないことを、この本で教わりました。
最初にも書きましたが、第2版は「JavaScript」で書かれているのですごく読みやすかったです。興味のある方は是非読んでみることをオススメします!!