リファクタリング実行の流れ
必ずブランチを切ること refactor/xxx のように、リファクタリングであることがわかるブランチ名にする
リファクタの際は必ず対象モジュールにテストがあるかを確認する
Red-Green-Refactor の原則に従い、リファクタにおいてもこのサイクルを遵守すること
リファクタ対象
references/plan.md から、高優先度・未対応のものを選ぶ
完了後は TODO を更新する
凝集度は機能的凝集に、結合度はメッセージ結合に
凝集度と結合度を改善することでコードの流れは格段に良くなります 以下の凝集度と結合どの内容をよく理解し、機能的凝集とメッセージ結合を目指しましょう
凝集度
1 -> 7 に向けてコードの品質は悪化するため、機能的凝集を目指します
-
機能的凝集(最良) 単一の機能だけを実現している 例: 2点間の距離を計算するモジュールは、これ以上意味のある部分に分解することが出来ないので、機能的凝集となります。
-
逐次的凝集
処理間で値の受け渡しがある 例: ファイルを取得し、変換して保存するなどがこれに当たります
- 通信的凝集
同じデータを使う処理群
例: あるデータに対して changeAll(data) とするとき、その中で changeA(data) -> changeB(data) -> changeC(data) といった処理が行われている
- 手順的凝集
特定の順序に意味がある処理 例: ファイル書き込み権限を確認してから、ファイルを書き込むなどがこれに当たります
- 時間的凝集
特定の時間に実行される処理がまとめられている
- 命令型プログラムに存在する不可避な時間軸(処理の順番) バックエンド例: main関数のセットアップ、ユースケース層の確立など。
- 論理的凝集
フラグなどで処理を切り替える 例: sendMessage(type) のように「type=text」「type=stamp」など条件によって分岐する形になる
- ユースケースは異なるが、処理が「なんとなく似ている」ためまとめてしまう
- DRY原則(Don't Repeat Yourself)を意識しすぎて、異なる責務の処理を1つの関数で扱う
- 偶発的凝集(最悪)
関連性のない処理が1つの関数にある 例: 現在時刻を取得しグローバル変数に入れるだけ、同時にユーザー名を取得し認証を行うなど、関係性がない処理が1つの関数にある
結合度
良いコードのためには、低い結合度を目指します
- メッセージ結合(最良)
値の受け渡しなし
引数のないやり取りです. 理想的なパターンですが、これを優先することで悪い凝集度のパターンになってしまってはいけません
- データ結合
必要な値だけ渡す. 理想的なパターンのひとつです
- スタンプ結合
構造体やクラスを丸ごと渡す. 不必要なデータまで渡してしまうため、結合度が高くなります
- 制御結合
フラグで相手の動作を制御. 相手の動作を制御するために、結合度が高くなります
→ 呼び出し先が論理的凝集になる
- 外部結合
public変数経由. 外部から変更される可能性があるため、結合度が高くなります
- 共通結合
グローバル変数共有. 外部から変更される可能性があるため、結合度が高くなります
- 内容結合(最悪)
他関数の内部を直接変更. 他関数の内部を直接変更するため、結合度が高くなります C言語でアドレスを直接操作. アドレスを直接操作するため、結合度が高くなります