最近コードの知識をインプットしているのでまとめてみる

2022/11/11に公開

参考資料:この記事は「良いコード・悪いコードで学ぶ設計入門」の2章をアウトプットしつつ書いています。

設計の入門知識

省略せずに意図する名前を設計する

  • 名前が短かくなる時間よりも、読みづらく意味不明なコードの方が何倍も時間がかかるので適切な名前で変数を宣言する
Class User extends Object {
  int a
  String n
  int uN
}

よりも

Class User extends Object {
  int age
  String name
  int userNumber
}

の方がいい、(例が極端すぎるが)
開発する上で周知の省略文字とかは省略してもいい

変数を使い回さずに目的ごとの変数を用意する

  • 変数に値を再度代入することを「再代入」と呼ぶ。再代入はコードの途中で変数の意味や用途が変わってしまう。
  • そのように変数を使い回すと、読み手が混乱し保守が困難になりバグの可能性が広がる
int damageAmount = playerArmer + playerWeaponPower;
int damageAmount = damageAmount - .....

再代入するよりも、丁寧に目的ごとの変数を用意する

int totalPlayerAttackPower = playerArmPower + playerWeaponPower;
int totalEnemyDefence = enemyBodyDefence + enemyArmorDefence;

int damageAmount = totalPlayerAttackPower - totalEnemyDefence;

totalPlayerAttackPower、totalEnemyDefenceに分けていることで雑に同じ変数を使うよりも変数の「役割」がわかりやすくなっている。

意味のあるまとまりでメソッド化

  • 消費税計算メソッド・所得税計算メソッドなど、意味を持つメソッドごとに関数として分ける。
  • ただ下手書きしてもどこからどこまでが何の処理なのかが読み手にわかりにくく、バグの元になる
int price;
int income;
double salesTaxRate;
double incomeTaxRate;

int salesTax = price * salesTaxRate;
int incomeTax = income * incomeTaxRate;

としても、意味の異なる計算がまとめてグチャグチャになってるのでわかりにくい。

int computeSalesTax(int price, double salesTaxRate){
  salesTax = price * salesTaxRate;
}//消費税の計算
int computeIncomeTax(int income, double incomeTaxRate){
  incomeTax = income * incomeTaxRate;
}// 所得税の計算

このように「消費税計算」「所得税計算」とメソッドを分けることで保守しやすいコードに近づく。
関数名も長くなろうともそれで後々読み手がメソッドの意味を確実に理解できるなら何の問題もない

関係しあう「データ」と「ロジック」を「クラス」にまとめる

  • 関係しあうメソッドと変数をクラスとしてまとめることで一箇所にくっつけておく(凝縮度を上げる)と、読み手としてもわかり易い設計になる。
  • また、クラスを作ると言うことはそのクラスのインスタンスは設計固有の「クラス型」とすることができるので型に合わない値を弾いたりしてより堅牢な設計にできる

①どこかに書かれる消費税計算ロジック(Bad)

int computeSalesTax(int price, double salesTaxRate){
  salesTax = price * salesTaxRate;
}//消費税の計算

②何処かに書かれる所得税計算ロジック(Bad)

int computeIncomeTax(int income, double incomeTaxRate){
  incomeTax = income * incomeTaxRate;
}// 所得税の計算

①、②どちらのロジックも関連しているロジックなので同じクラスにまとめる(Good◎)。以下。

taxCalc.dart
Class Tax extends statelessWidget {

  int price;
  double salesTaxRate;
  int income;
  double incomeTaxRate;

  int computeSalesTax(int price, double salesTaxRate){
    salesTax = price * salesTaxRate;
  }//消費税の計算

  int computeIncomeTax(int income, double incomeTaxRate){
    incomeTax = income * incomeTaxRate;
  }//所得税の計算

}

Taxクラスに値とロジックをまとめていくと、関係を持つメンバ同士が近づき見やすくなる。また、Taxクラス型としてインスタンスを作れるので不正値の混入を防ぐことにも繋がる。

そもそもこのようにしてクラス型などを作れることがオブジェクト指向の強みの一だと思うのでそれに乗っかっていけるような設計をしようってことですよね〜

GitHubで編集を提案

Discussion