プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • リファクタリング
  • 【リファクタリング】変更な大変なプログラムと改善策、「区分」や「タイプ」の実装方法
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【リファクタリング】変更な大変なプログラムと改善策、「区分」や「タイプ」の実装方法

08.01

  • miyabisan2
  • コメントを書く

この記事は2分で読めます

わかりにくプログラムの特徴

メソッドが長い

理解するのが大変。特にif-elseが入り組んだメソッドは理解が骨が折れる。

引数が増えるたびにメソッドも長くなりif文も増える。

クラスが大きい

関心ごとを詰め込みすぎないこと。

引数が多い。

どの引数が関係し、どの引数が関係しないか見極めに時間がかかる。

最初からわかりにくいわけではない。

プログラムが改修されるたびにどんどんメソッドや変数の追加などを後付けでしていくので、時間と共にどんどんわかりづらくなっていきます。

改善策

一つの変数を使い回さずに、用途ごとに変数を用意する。

第三者への説明にもなる。

重複コードはメソッドとして切り出す。

クラスが大きくなったら関連するクラスだけ抜き出す。

基本的には、メソッドがどのインスタンス変数を使っているかで判断するのが良いでしょう。

パッケージを使ってクラスを整理する。

クラスの数が増えてくるとどこに何が書いてあるか見つけにくくなります。それを整理するのがJavaで言えばパッケージです。

なお、パッケージ内のクラスの数が増えてきたらさらにサブパッケージに分けると良いでしょう。

また、パッケージ名が長くなるようであれば、階層化して一つ一つのパッケージ名を短くすることを検討すると良いでしょう。

データクラスをそもそも作らない。

getterメソッドとかも不要です。インスタンス変数を加工した結果を返すメソッドであれば問題ないです。

インスタンス変数を使わないメソッドを作らない。

インスタンス変数を使わずに、引数だけを使うメソッドをもし見つけたらそのメソッドは無意味になります。そういうメソッドを見つけたら、引数を渡している側のクラスに移動させるなど検討した方が良いでしょう。

データクラスと機能クラスに分けない。

ロジックとデータは同じクラスに持たせる。クラスを使う側のクラスでロジックが呼び出された場合は、業務クラス側にロジックを預けるよう書き直す。

業務に対応したクラスを作る。(ドメインオブジェクト)

業務データと業務ロジックを一つにまとめたオブジェクトを「ドメインオブジェクト」と呼びます。

値を扱う専用のクラスを作る。(値オブジェクト)

基本的に不変であるべきです。(setterとかで書き換えられないようにするべき)

特徴

  • インスタンス変数はコンストラクタで生成時に行う。
  • setterは作らない。
  • 別の値が必要であれば、別オブジェクトを作る。
電話番号型

普通のStringとかにしてしまうと思わぬ値が来ることになったりする。

相手のシステムとやり取りするインターフェース

コレクションや配列を扱う場合は専用のクラスにする。

コレクションや配列を操作するロジックなどは、普通に実装する場合かなり複雑になるため。専用のクラスを作る。(Reactで言えばuseReducerや、Redux)

1
例:Customerの配列だけ持ったCustomersクラスを作るなど。

特徴

インスタンス変数は該当のコレクションだけにする。
コレクションへの操作はメソッドで行う形にする。
元の値をそのまま変更させず、渡す場合はnewで必ず別オブジェクトを渡すようにする。

getListなどでコレクションをそのまま外部に渡してしまうと、外部からでもコレクションを色々操作できてしまうためコレクションの状態が不安定になってしまうため。(元のオブジェクトは直接は弄らせないという副作用を起こさせない。Reduxと同じ思想)

「区分」や「タイプ」の実装方法

if文やswitch文が増えます。

対策

判断のロジック(isXXX)と、計算ロジック(calcXXX)をメソッド化する。

後述するelseを書かないというためにもこれは使えます。

elseを書かない。

できるだけ「早期リターン」します。(「ガード節」ともいうらしいです。)、場合分けのコードがすっきりして読みやすくなります。

  • if (isXXX) return calcXXX
  • if (isYYY) return calcYYY

複文が単文にもなり疎結合になるので非常にわかりやすくなりますし、順番を並び替えてもうまく動きます。

区分クラスを作ったり、インターフェイスを作る。

また、ほぼ似ているクラスができるのであればインターフェイス化して、呼び出す側からポリモーフィズムなどで効率的に呼び出せるようにしましょう。

enum(列挙型)を使う。
スポンサーリンク
  • 2021 08.01
  • miyabisan2
  • コメントを書く
  • リファクタリング
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2019 12.12

    【リファクタリング】「命名規則」の考え方(定数など)

  2. 2018 03.24

    【Javaリファクタリング】その3:脱ぬるぽ!(Null(ヌル)オブジェクトの活用)

  3. 2021 08.21

    【リファクタリング】共通処理の良い書き方(Common関数やデータクラスの問題点なども)

  4. 2021 08.17

    【オブジェクト指向】ベストプラクティス(デメテルの法則なども)

  5. 2021 08.28

    【リファクタリング】「クラスのよくある命名」

  6. 2018 03.24

    【プログラミング】パッケージ、メソッド、クラス、変数名等の命名規則

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【Web】「CORS」を使わないSOPの緩和方法

【DDD】三層 + ドメインモデル

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー