<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Refactoring on Shiglass</title>
    <link>https://hirotoshimizu.github.io/categories/refactoring/</link>
    <description>Recent content in Refactoring on Shiglass</description>
    <generator>Hugo -- gohugo.io</generator>
    <lastBuildDate>Mon, 21 Feb 2022 18:04:23 +0900</lastBuildDate><atom:link href="https://hirotoshimizu.github.io/categories/refactoring/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Move Statements Into Function</title>
      <link>https://hirotoshimizu.github.io/posts/move-statements-into-function/</link>
      <pubDate>Mon, 21 Feb 2022 18:04:23 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/move-statements-into-function/</guid>
      <description>ステートメントの関数内への移動 動機 重複の除去は、健全なコードを導くための最もすぐれた経験則の1つ。特定の関数を呼び出すたびに同じコードが実行されていたら、反復コードを関数自体に組み込むことを検討する。 そうすることで、反復コードに将来変更が生じた場合でも、1箇所だけを修正すれば全ての呼び出し側で使えるようになる。将来、反復コードに差異が発生した場合は、「ステートメントの呼び出し側への移動」を行うことで、反復コード（またはその一部）を簡単に元の場所に移動できます。
ステートメントを関数に移動するのは、それを呼び出し先の関数の一部とみなすほうが理解しやすい場合です。呼び出し先の関数の一部としては意味をなさないものの、一緒に呼び出す必要がある場合は、そのステートメントと呼び出し先の関数を対象にして「関数の抽出」を行う。
手順  反復コードが移動先の関数呼び出しに隣接していない場合は、「ステートメントのスライド」を行って隣接させる。 移動元の関数の呼び出し元が関数だけだった場合は、移動元の関数からコードをカットし、移動先の関数にペーストして、テストを行い、残りの手順を無視する。 複数の呼び出し元がある場合は、いずれかの呼び出しに対して「関数の抽出」を行い、移動先の関数呼び出しと移動したいステートメントを抽出する。名前は一時的なものにするが、簡単に grep できる名前にする。 他のすべての呼び出しを変更して、新しい関数を使うようにする。変更のたびにテストする。 元の呼び出しの全てで新しい関数を使うようになったら、「関数のインライン化」を行って元の関数を新しい関数に完全にインライン化し、元の関数を削除。 「関数名の変更」を行って、新しい関数の名前を元の関数と同じ名前に変更する。  </description>
    </item>
    
    <item>
      <title>Move Field</title>
      <link>https://hirotoshimizu.github.io/posts/move-field/</link>
      <pubDate>Mon, 21 Feb 2022 16:14:24 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/move-field/</guid>
      <description>フィールドの移動 動機 データ構造が正しくないとわかったら、すぐに変更することが重要です。データ構造の欠陥を放置すると、その後長きにわたって、思考を混乱させ、コードを複雑化する原因となる。
あるレコードを関数に渡す際に、必ず別レコードのフィールドも渡す必要がある場合、フィールドを移動したくなります。まとめて関数に渡すデータは、通常なら同じレコードにまとめるべきで、それによりデータの関係が明確になる。あるレコードを更新するたびに別レコードのフィールドも更新していることは、フィールドの場所が間違っていることを示唆している。複数の場所にある同じフィールドを更新しなければならないことは、フィールドを別の場所に移動して一度だけで更新できるようにすべきことを示している。
フィールドの移動は、通常、より広範囲な変更の一部として行います。フィールドの移動が完了すると、そのフィールドの利用プログラムの多くにとっては、移動先のオブジェクトのほうが移動元よりも適切なデータのアクセス先となる。しかし、そのリファクタリングは後回しにする。別のケースとして、データの利用方法がネックになり、その時点では「フィールドの移動」を行えない場合がある。そうしたときには最初にデータの利用側をリファクタリングし、その後でフィールドを移動する必要がある。
手順  移動元のフィールドをカプセル化する。 テスト 移動先にフィールド（およびアクセサ）を作成する。 静的解析を実行する。 移動元のオブジェクトから移動先のオブジェクトを参照できるようにする。 移動先への参照として、既存のフィールドやメソッドが使えるかもしれない。使えない場合は、参照用メソッドを簡単に作れるかどうかを調べる。うまくいかない場合は、移動元のオブジェクトに移動先のオブジェクトを格納する新しいフィールドを作成する必要があるかもしれない。これを恒久的な変更としてもよいが、より広範囲のリファクタリングがある程度進むまでの一時的な変更としてもよい。 移動先のフィールドを使うようにアクセサを調整する。 移動先のオブジェクトが移動元のオブジェクト間で共有される場合は、移動先と移動元の両方のフィールドを更新するように setter を変更した上で「アサーションの導入」を施し矛盾する更新を検出できるようにする。矛盾する更新がないと判断できたら、移動先のフィールドを使うようにアクセサを変更する。 テスト 移動元のフィールドを削除する。 テスト  </description>
    </item>
    
    <item>
      <title>Move Function</title>
      <link>https://hirotoshimizu.github.io/posts/move-function/</link>
      <pubDate>Mon, 21 Feb 2022 11:27:22 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/move-function/</guid>
      <description>関数の移動 動機 関数を移動する最も直観的な理由は、その関数が存在するコンテキストの要素よりも他のコンテキストの要素を多く参照しえちる場合。移動によって、関数をそれらの要素と一緒にすると、カプセル化が改善することがよくある。別の関数内で定義されたヘルパー関数が単体で有用な場合は、よりアクセスしやすい場所に移動すると有意義。 関数の移動の判断はたいてい困難を伴います。その判断を下すには、その関数の現在のコンテキストを移動先候補のコンテキストを調べます。どの関数が移動したい関数を呼び出すか、移動したい関数がどのデータを使っているかを調べる必要がある。
関数のグループのために新しいコンテキストが必要になるケースは多いため、「関数群のクラスへの集約」や「クラスの抽出」によって新しいコンテキストを作成する。関数をどこに配置するのが最適かを決めるのは難しいかもしれませんが、通常はその選択が難しければ難しいほど、配置先を決める重要性は下がる。関数をあるコンテキストに実際に移動してみて、どれだけうまく適合するかを調べることは有意義。うまく適合しなかったしても、後からいつでも移動できる。
手順  移動対象の関数が現在のコンテキストで使用しているプログラム要素をすべて調べる。それらも移動すべきかどうかを検討する。 呼び出している関数にも移動すべきものがあった場合、通常、まずはその関数から移動する。こうすることで、一連の関数の移動を依存性の低い関数から抽出できる。
上位レベルの関数がサブ関数群の唯一の呼び出し元だった場合、それらのサブ関数群を上位の関数にインライン化し、移動した後で再抽出してもよい。 選択した関数がポリモーフィックなメソッドかどうかを確認する。 オブジェクト指向言語の場合、スーパークラスとサブクラスに注意する必要がある。 関数を移動先のコンテキストにコピーする。新居となる移動先に関数が適合するように調整する。 コード本体が元のコンテキスト内の要素を使用する場合、それらの要素をパラメータとして渡すか、あるいは元のコンテキストへの参照を渡す必要がある。
関数を移動すると、新しいコンテキストにうまく適合する別の名前を付けたくなることがよくある。 静的解析を実行する。 元のコンテキストから移動後の関数を参照できるようにする。 テスト 元の関数に対して「関数のインライン化」の適用を検討する。 元の関数は委譲関係として残しても良い。しかし、移動した関数を呼び出し元が簡単に呼び出せるなら、余分な仲介者は取り除くほうが良い。  </description>
    </item>
    
    <item>
      <title>Encapsulate Record</title>
      <link>https://hirotoshimizu.github.io/posts/encapsulate-record/</link>
      <pubDate>Mon, 21 Feb 2022 10:39:13 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/encapsulate-record/</guid>
      <description>レコードのカプセル化 動機 レコード構造は、一般的な機能で、それらは関連するデータを一緒にグループ化する直観的な方法を提供し、緩いデータの群れの代わりに意味のあるデータ単位を渡すことを可能にする。 変更可能なデータについてはレコード化するよりオブジェクト化した方が良い。オブジェクトであれば、保持されているものを隠蔽し、値すべてに対するメソッドを用意できる。 オブジェクトのユーザーは、どれが保持され、どれが計算されるかを知る必要がない。このカプセル化は名前の変更にも役立つ。フィールド名を変更しても、新たな名前と古い名前の両方のメソッドが使えるため、呼び出し側を徐々に置き換えていくことが可能になる。
手順  レコードを保持する変数に「変数のカプセル化」を施す。 コード名をカプセル化するための関数には、検索しやすい名前を付ける。 変数の中身を、レコードをラップする簡単なクラスに置き換える。レコードをそのまま返すアクセサをクラスに定義する。変数をカプセル化する関数を変更して、アクセサを使うようにする。 テスト レコードそのものではなくオブジェクトを返す関数を用意する。 レコードの使用箇所ごとに、レコードを返す関数の呼び出しを、オブジェクトを返す関数の呼び出しに置き換える。フィールドデータの取得にはオブジェクトのアクセサを使うようにする。必要ならばそのためのアクセサを作る。変更のたびにテストする。 入れ子構造を持つなど、レコードが複雑な場合は、まずデータを更新しているクライアントのコードに注目する。データを読むだけのクライアントについては、コピーやプロキシを返すことを検討する。 生データへのアクセサと、検索しやすくしておいたレコードそのままを返す関数をクラスから取り除く。 テスト レコードのフィールド自体が構造体である場合、「レコードのカプセル化」と「コレクションのカプセル化」を再帰的に施すことを検討する。  </description>
    </item>
    
    <item>
      <title>Split Phase</title>
      <link>https://hirotoshimizu.github.io/posts/split-phase/</link>
      <pubDate>Mon, 21 Feb 2022 09:42:00 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/split-phase/</guid>
      <description>フェーズの分離 動機 1つのコードが異なる2つの処理を行っている場合、別々のモジュールに分離する方法がないか探す。 分離に力を咲くのは、トピックごとに分けて対処でき、両方を1度に頭に入れる必要がないから。
振る舞いを順次的な2段階のフェーズに分けるという方法がある。 処理を始める前に、入力をメイン処理に都合の良い形式に整形する。
手順  後半となるフェーズのコードを、関数として抽出する。 テスト 抽出した関数に追加される引数として、中間データ構造を導入する。 テスト 抽出した後半のフェーズの各パラメータを確認する。それらが前半のフェーズでも使われているなら、中間データ構造へと移す。1つ移すごとにテストする。 あるパラメータについては後半のフェーズで使うべきでないこともある。その場合は、そのパラメータを使用した結果を、中間データ構造のフィールドとして抽出する。その後「ステートメントの呼び出し側への移動」を施して、この中間データ構造に値を格納している行を移動する。 前半のフェーズのコードに「関数の抽出」を施し、中間データ構造を返すようにする。 前半のフェーズを変換オブジェクトとして抽出してもよい。  </description>
    </item>
    
    <item>
      <title>Combine Functions Transform</title>
      <link>https://hirotoshimizu.github.io/posts/combine-functions-transform/</link>
      <pubDate>Mon, 21 Feb 2022 09:00:08 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/combine-functions-transform/</guid>
      <description>関数群の変換への集約 動機 ソフトウェアの多くは、プログラムにデータを投入して、そこからさまざまな派生情報を計算する処理を含んでいる。派生値はさまざまな箇所で必要になり、派生値が参照されるたびに繰り返される。 こうした派生値はまとめるのが望ましく、一貫した探しやすい場所で更新がおこなわれるようにして、重複したロジックは避けるべき。
その1つの方法はデータ変換関数を使うことです。これは元データを入力としてすべての派生値を計算し、それらを出力データのフィールドとして設定するものです。そうすることで、派生値について調べたいときは変換関数だけを見ればよくなる。
もう1つの方法が「関数群のクラスへの集約」。元データに基づいてクラスを構成し、ロジックをそのクラスのメソッドに移す。
重要な違いは、元データがコード内で更新される場合は、クラスを使うほうが良い。変換関数を使うと派生データが新たなレコードに保持されます。そのため元のデータが変更されると不整合が生じる。
関数群を集約したい理由として、派生値を求めるロジックの重複をさけたいということがある。それだけなら、単に「関数の抽出」をロジックに適用する手もあるが、関数が扱うデータ構造と近い位置に置かれていないと、関数を見つけ出すのが難しくなる。変換関数を使うと、探すのが容易になり利用もしやすくなる。
手順  変換されるレコードを入力とし、同じ値を返す変換関数を作る。
通常、この関数の中ではレコードのディープコピーが行われる。この変換によって元のレコードが変更されていないことを確認するテストを書くとよい。 ロジックを選んでその本体を変換関数側に移し、レコードに新たなフィールドを設ける。そのフィールドを使うようにクライアント側のコードを変更する。 ロジックが複雑ならば、まず「関数の抽出」を施す。 テスト その他の関連した関数群について上記の手順を繰り返す。  </description>
    </item>
    
    <item>
      <title>Combine Functions Into Class</title>
      <link>https://hirotoshimizu.github.io/posts/combine-functions-into-class/</link>
      <pubDate>Sun, 20 Feb 2022 17:40:07 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/combine-functions-into-class/</guid>
      <description>関数群のクラスへの集約 動機 共通のデータに対して互いに関わりの深い処理を行う一群の関数があれば、クラスを定義するチャンスと考える。（共通データは通常は関数呼び出しの際に引数として渡さる。）クラスを使うことで、これらの関数が共有する環境がより明示的になり、関数の引数が大幅に減ることで、オブジェクト内の関数呼び出しを単純化できます。そうしたオブジェクトをシステムの他の部分に参照として渡すのも容易になる。
このリファクタリングは既存の関数群を体系化するだけではなく、他で断片的に計算を行っている箇所を特定し、新たなクラスのメソッドとしてリファクタリングする良い機会も与えてくれる。
手順  関数間で共有しているデータのレコードに「レコードのカプセル化」を施す。
関数間で共有しているデータが、レコード構造としてまとめられていない場合は、「パラメータオブジェクトの導入」を施し、それらをまとめるレコードを作る。 「関数の移動」を適用して、共通のレコードを扱う関数をそれぞれ、新たなクラスへと移す。
関数呼び出しの引数のうち、クラスのメンバになっているものは、引数のリストから取り除くことができる。 データを操作するロジックの断片があればそれぞれ、「関数の抽出」で抽出してクラスに移す。  </description>
    </item>
    
    <item>
      <title>Introduce Parameter Object</title>
      <link>https://hirotoshimizu.github.io/posts/introduce-parameter-object/</link>
      <pubDate>Sun, 20 Feb 2022 15:16:18 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/introduce-parameter-object/</guid>
      <description>パラメータオブジェクトの導入 動機 データ構造体にまとめることには意味があり、データ項目間の関係を明示するとができる。 新たな構造体を使えば、関数のパラメータ数は少なくて済みます。その構造体を使うすべての関数が、構造体の要素を取得するのに同じ名前を使うことで、一貫性の向上にも役立ちます。 このリファクタリングの真価は、コードにより深い変化を引き起こすことにあります。新たな構造体を特定したら、その構造体を使うようにプログラムの振る舞いを改めます。一連の共通関数群になることも、データ構造とそれらの関数を組み合わせたクラスになることもあります。この過程でコードの概念的な構図が変化することもある。そうした構造体を新たな抽象に引き上げると、問題領域の理解がすっきりする。
手順  ふさわしい構造体がまだ存在しないなら、作成する。 後で振る舞いをまとめやすいのでクラスにすることが多い、構造体が「値オブジェクト」なのか確認するとよい。 テスト 関数宣言の変更を施し、新たな構造体用のパラメータを追加する テスト 新たな構造体の正しいインスタンスを渡すように各呼び出し側を修正する。1つの呼び出しを修正するごとにテストする 元のパラメータを使用している箇所を、新たな構造体の要素を使うように1つひとつ置き換える。元のパラメータを削除し、テストする。  </description>
    </item>
    
    <item>
      <title>Rename Variable</title>
      <link>https://hirotoshimizu.github.io/posts/rename-variable/</link>
      <pubDate>Sun, 20 Feb 2022 14:59:37 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/rename-variable/</guid>
      <description>変数名の変更 動機 変数はうまく名前を付けさえすれば、目的説明する上で非常に役立ちます。しかし注意深く考えていない場合やユーザーのニーズが変わってプログラムの目的が変わったから、などがあり不適切な名前となることがある。
手順  変数が広く使われている場合、「変数のカプセル化」を検討する。 変数への参照をくまなく探し、それらをすべて変更数。
変数が別のコードベースから参照されている場合、その変数は公開されているので、このリファクタリングを行うことはできない。
変数が変更されない場合、変数を新たな名前の変数にコピーしてから、徐々に置き換えていき、その都度テストする テスト  </description>
    </item>
    
    <item>
      <title>Encapsulate Variable</title>
      <link>https://hirotoshimizu.github.io/posts/encapsulate-variable/</link>
      <pubDate>Sun, 20 Feb 2022 12:05:14 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/encapsulate-variable/</guid>
      <description>変数のカプセル化 動機 スコープが大きくなるにつれて変更が困難になっていく。そのため広い範囲でデータを移動したいといは、カプセル化して、変数へのアクセスを関数経由にするのが非常に良いやり方。これでデータの再構成という困難な作業を、関数の再構成というより簡単な作業に変えることができる。
それ以外にデータの変更や参照を監視できるという明確な利点を得られる。データ更新の際の検証や後処理を追加するのも簡単。
スコープが1つの関数より大きいものは、関数を通じてのみアクセスできるようにし、データのスコープが大きくなるほどカプセル化はより重要になる。
手順  変数を参照・更新するためのカプセル化用関数を作る。 静的チェックを実行する。 変数への参照を、1つひとつ適切なカプセル化関数の呼び出しに置き換える。置き換えるごとにテストする。 変数の可視性を制限する。
変数への直接アクセスを防げないことがよくある。その場合、変数名を変更してテストすることで、置き換えが漏れた参照を見つけることができる。 テスト 変数の値がレコードの場合、「レコードのカプセル化」を検討する。  </description>
    </item>
    
    <item>
      <title>Change Function Declaration</title>
      <link>https://hirotoshimizu.github.io/posts/change-function-declaration/</link>
      <pubDate>Sun, 20 Feb 2022 09:32:33 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/change-function-declaration/</guid>
      <description>関数宣言の変更 動機 関数宣言はソフトウェアシステムにおける継ぎ目となる。多くの部分が継ぎ目に依存し、良い継ぎ目があればシステムに新たな部品を追加するのは簡単。悪い継ぎ目は常に問題の発生源になる。
継ぎ目の要素で最も重要なのは関数名です。もし間違った名前の関数を見たら、少しでも名前がわかり次第、断固として変更していかなければなりません。
関数の名前を改善していくための良い方法は、関数の目的をコメントとして書くこと。そのコメントを名前に変更する。
手順 変更内容を吟味して、宣言と呼び出しとを一度で簡単に変更できるかを検討する。もしできるなら簡易な手順を実行する。 そうでなければ移行手順を選択して呼び出し側より漸進的に変更していく。 この手順が大きな意味を持つのは、呼び出し箇所が多い場合や（公開されたAPIのように）呼び出し箇所が手の届かないところにある場合、関数がポリモーフィックなメソッドである場合、関数宣言に複雑な変更を加える場合です。
簡易な手順  パラメータを削除する場合、それが関数内部で参照されていないことを確認する。 関数宣言を望ましいものに変更する。 古い関数宣言へのすべての参照を探し、新しいものに変更する。 テスト 名前の変更とパラメータの追加の両方がある場合には、それぞれ別のステップで実施する。  移行手順  必要なら関数の本体をリファクタリングして、移行の抽出のステップを実施しやすくしておく。 関数本体に関数の抽出を施して、新たな関数を作る。
新たな関数の名前を古いものと同じにする予定なら、新たな関数に判別しやすい名前を一時的に付けておく。 抽出した関数が追加のパラメータを必要とする場合、簡易な手順により追加を行う。 古い関数に「関数のインライン化」を施す。 一時的な名前を使った場合、「関数宣言の変更」を再び実施し、元の名前に戻す。 テスト  </description>
    </item>
    
    <item>
      <title>Inline Function</title>
      <link>https://hirotoshimizu.github.io/posts/inline-function/</link>
      <pubDate>Sun, 20 Feb 2022 07:55:49 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/inline-function/</guid>
      <description>関数のインライン化 動機 意図がわかるように命名された短い関数を使うことはコードを読みやすくする。しかし、関数の本体がその名前と同じくらいわかりやすいことがある。そうしたときには関数を取り除く。
「関数のインライン化」は、うまく分割できない関数群があるときにも使われる。こうしたときは、それらを1つの大きな関数にインライン化してから、望ましい形の関数群として再抽出すればよい。
通常、「関数のインライン化」を使うのは、間接化しすぎた結果、どの関数も別の関数へ委譲しているだけにしか見えず、委譲に次ぐ委譲の途中で迷っている状態。
手順  関数がポリモーフィックなメソッドでないことを確認する。
クラスのメソッドで、サブクラスでオーバーライドされている場合はインライン化できない。 この関数の呼び出し元をすべて見つける。 関数の各呼び出し元をすべて見つける。 1つ置き換えるごとにですとする。
すべてのインライン化を一度にする必要はない。一部のインライン化がやりにくいようなら、機会を持って徐々に進めてもよい。 関数の定義を取り除く   Before def say_state(self): print_state(self) def print_state(self): print(f&amp;#34;I&amp;#39;m going {self.speed} kph!&amp;#34;) After def say_state(self): print(&amp;#34;I&amp;#39;m going {} kph!&amp;#34;.format(self.speed)) </description>
    </item>
    
    <item>
      <title>Solid</title>
      <link>https://hirotoshimizu.github.io/posts/solid/</link>
      <pubDate>Fri, 18 Feb 2022 10:33:01 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/solid/</guid>
      <description>よくできたソフトウェアシステムは、クリーンなコードを書くことから始まる。レンガの出来が悪ければ、その建築は優れたものにはならない。一方、たとえよくできたレンガを使っても、ぐちゃぐちゃなもの作ってしまうことがあり得る。そこで登場するのが「SOLID」原則。
SOLID原則は、関数やデータ構造をどのようにクラスに組み込むのか、そしてクラスの相互接続をどのようにするのかといったことを教えてくれる。　SOLID原則の目的は、以下のような性質を持つ中間レベルのソフトウェア構造を作ること。
 変更につよいこと 理解しやすいこと コンポーネントの基盤として、多くのソフトウェアシステムで利用できること  Single Responsibility Principle 個々のモジュールを変更する理由がたったひとつだけになるように、ソフトウェアシステムの構造がそれを使う組織の社会的構造に大きな影響を受けるようにする。
モジュールはたったひとつのアクターに対して責務を負うべきである。
Opne Closed Principle ソフトウェアの構成要素は拡張に対しては開いていて、修正に対しては閉じていなければならない。
ソフトウェアの振る舞いは、既存の成果物を変更せず拡張できるようにすべき。
Liskov Substitution Principle サブクラスは、スーパークラスと置換可能でなければならない。
Interface Segregation Principle 包括的なインターフェースがあるより、いくつかの特定のインターフェースに分割すべき。
Dependency Inversion Principle ソースコードの依存関係が（具象ではなく）抽象だけを参照しているシステムが最も柔軟である。</description>
    </item>
    
    <item>
      <title>Extract Function</title>
      <link>https://hirotoshimizu.github.io/posts/extract-function/</link>
      <pubDate>Fri, 18 Feb 2022 08:29:55 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/extract-function/</guid>
      <description>動機 「関数の抽出」はきわめて頻繁に行われるリファクタリング。
いつ独立した関数として取り出すかというは「2回以上使われるコードはそれ自体を関数にすべき」のように、再利用に基づいている。
しかし、最も納得できるのは意図と実装の分離です。何をしているか調べなければわからないコードの断片があるとしたら、「何」をしているかを示す名前の関数として抽出すべきです。そうすれば関数を読み返すだけで関数の目的がすぐに伝わってきます。
手順  新たな関数を作り、その意図に沿って命名する（どうやるかではなく、何をするかによって名づける。） 抽出したいコードを、元の関数から新たな関数にコピーする。 抽出したコードを調べて、元の関数ではスコープ内だったが抽出後の関数ではスコープ外になった変数を特定する。それらをパラメータとして渡す。 全ての変数を処置したらコンパイルする。 元の関数に残った抽出前のコードを、抽出された関数への呼び出しに置き換える。 テストする。 残りのコードを見て、抽出したコードと同じまたは類似したコードを探し、「関数呼び出しによるインラインコードの置き換え」を適用し、新しい関数を呼ぶ形にできないか検討する。  Before from enum import Enum class Category(Enum): A = 1 B = 2 C = 3 def calculate_tax(category: Category, income: int) -&amp;gt; int: if category == Category.A: discount = 10 elif category == Category.B: discount = 5 else: discount = 0 return income * (100 - discount) // 100 After from enum import Enum class Category(Enum): A = 1 B = 2 C = 3 def calculate_tax(category: Category, income: int) -&amp;gt; int: discount = calc_discount(category) return income * (100 - discount) // 100 def calc_discount(category: Category) -&amp;gt; int: if category == Category.</description>
    </item>
    
    <item>
      <title>Code Smells</title>
      <link>https://hirotoshimizu.github.io/posts/code-smells/</link>
      <pubDate>Thu, 17 Feb 2022 15:14:16 +0900</pubDate>
      
      <guid>https://hirotoshimizu.github.io/posts/code-smells/</guid>
      <description>Bloaters  長い関数(Long Method)
オブジェクトそのものの受け渡し、関数の抽出、コマンドによる関数の置き換え、問い合わせによる一時変数の置き換え、条件記述の分解、パラメータオブジェクトの導入、ポリモーフィズムによる条件記述の置き換え、ループの分離 巨大なクラス(Large Class)
クラスの抽出、サブクスによるタイプコードの置き換え、スーパークラスの抽出 データの群れ(Data Clumps)
オブジェクトそのものの受け渡し、クラスの抽出、パラメータオブジェクトの導入 長いパラメータリスト(Long Parameter List)
オブジェクトそのものの受け渡し、関数群のクラスへの集約、問い合わせによるパラメータの置き換え、パラメータオブジェクトの導入、フラグパラメータの削除 基本データ型への執着(Primitive Obsession)
オブジェクトによるプリミティブの置き換え、クラスの抽出、サブクラスによるタイプコードの置き換え、パラメータオブジェクトの導入、ポリモーフィズムによる条件記述の置き換え  Tool Abusers  Switch Statements 相続拒否(Refused Bequest)
委譲によるサブクラスの置き換え、委譲によるスーパークラスの置き換え、フィールドの押し下げ、メソッドの押し下げ クラスのインターフェース不一致(Alternative Classes w/ Different Interfaces)
関数宣言の変更、関数の移動、スーパークラスの抽出 一時的属性(Temporary Field)
関数の移動、クラスの抽出、特殊ケースの導入  Change Preventers  Divergent Change 変更の分散(Shotgun Surgery)
関数群のクラスへの集約、関数群の変換への集約、関数の移動、関数のインライン化、クラスのインライン化、フィールドの移動、フェーズの分離 Parallel Inheritance Hierarchies  Dispensables  Lazy Class 疑わしき一般化(Speculative Generality)
関数宣言の変更、関数のインライン化、クラス階層の平坦化、クラスのインライン化、デッドコードの削除 データクラス(Data Class) 重複したコード(Duplicated Code)
関数の抽出、ステートメントのスライド、メソッドの引き上げ  Couplers  特性の横恋慕(Feature Envy)
関数の移動、関数の抽出 Inappropriate Intimacy メッセージの連鎖(Message Chains)</description>
    </item>
    
  </channel>
</rss>
