7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Unity C#】DRY原則を勉強する

Last updated at Posted at 2021-09-20

前置き

書籍を読んだり、ググったりして、自分に分かりやすいようにまとめた記事です。
より詳しく知りたい方は、下記の参考文献を読んでみてください。

参考文献

達人プログラマー ―熟達に向けたあなたの旅― 第2版 | Amazon
あなたはDRY原則を誤認している? - Qiita
本当の問題にたどり着かない――思考の重複を起こさないための「DRY」原則:問題解決力を高めるコツはプログラミングの原則・思考にあり - @IT

DRY原則(Don't Repeat Your Self) とは

  • 一言でいうと知識を二箇所以上に重複させるな
  • 同じロジックが複数箇所で使われるなら、コピペは厳禁
    • 同じようなコードが複数あると、修正する際に修正漏れする危険性がある
    • 同じようなコードだと思って、修正不要な箇所に誤って手を加えることになる可能性もある

- 誤解しがちなところは**「コードを重複させるな」ではない** - 「知識」や「意図」の二重化についての原則 - 異なった場所に同じことを表現するという問題を避けるための - コードだけでなく、データベーススキーマ、テスト計画、ビルドシステムやドキュメントなども含まれる

コードの二重化

商品情報から消費税を計算したり、値引した価格を求めたりするコード例

Product.cs
public class Product
{
    public string Name { get; set; }
    public int Price { get; set; }
}
PriceCalculation.cs
public class PriceCalculation
{
    /// <summary>
    /// 商品の10%を求める
    /// </summary>
    /// <param name="product"></param>
    /// <returns></returns>
    public int GetTenPercentPrice(Product product)
    {
        return product.Price * 0.10;
    }

    /// <summary>
    /// 商品の消費税を求める
    /// </summary>
    /// <param name="product"></param>
    /// <returns></returns>
    public int GetConsumptionTax(Product product)
    {
        return product.Price * 0.10;
    }
}

改善方法

  • GetTenPercentPriceGetConsumptionTax のどちらも計算内容は同じ = 共通化できる
    • Product.cs の内容は同じなので割愛
PriceCalculation.cs
public class PriceCalculation
{
    /// <summary>
    /// 商品の10%を求める
    /// </summary>
    /// <param name="product"></param>
    /// <returns></returns>
    public int GetTenPercentPrice(Product product)
    {
        return product.Price * 0.10;
    }
}

本当にこれで良いの??

  • 消費税が10%から8%に変更されたとする
    • GetTenPercentPrice を以下のように変更する可能性あり
PriceCalculation.cs
public class PriceCalculation
{
    /// <summary>
    /// 商品の8%値引きした価格(消費税)を求める
    /// </summary>
    /// <param name="product"></param>
    /// <returns></returns>
    public int GetEightPercentPrice(Product product)
    {
        return product.Price * 0.08;
    }
}
  • 消費税の計算に関する修正としては問題ないが「10%値引きした価格計算」する処理がなくなった
    • 値引き計算している処理のところでコンパイルエラーや意図しない挙動になってしまう
    • 共通化しすぎかも??

本当の改善方法(例)

  • 「値引き価格計算」と「消費税計算」は別々に管理するほうがよいかも
    • 変更する理由を明確に分離できる
DiscountCalculation.cs
public class DiscountCalculation
{
    /// <summary>
    /// 商品の10%を求める
    /// </summary>
    /// <param name="product"></param>
    /// <returns></returns>
    public int GetTenPercentPrice(Product product)
    {
        return product.Price * 0.10;
    }
}
TaxCalculation.cs
public class TaxCalculation
{
    /// <summary>
    /// 商品の消費税を求める
    /// </summary>
    /// <param name="product"></param>
    /// <returns></returns>
    public int GetConsumptionTax(Product product)
    {
        return product.Price * 0.10;
    }
}

コードのコメントによる二重化

コード例

Bullet.cs
// 違反例
public class Bullet : MonoBehaviour
{
    /// <summary>
    /// Enemyオブジェクトに衝突したときに発火する
    /// GameObjectに格納している IEnemy の Component を取得
    /// Enemyオブジェクトにダメージを与える
    /// Component が取得できなかったら何もしないで処理を終了する
    /// </summary>
    /// <param name="collision"></param>
    void OnCollisionEnter(Collision collision)
    {
        var hit = collision.gameObject;
        var enemy = hit.GetComponent<IEnemy>();

        if (enemy == null)
            return;

        enemy.ApplyDamage();
    }
}

良くない点

  • コメントとコードで、この関数の情報が2度繰り返されている
    • コードを修正した場合、コメントを修正する必要がある
      • コメント修正を忘れる可能性大
      • 時間が経つと、コードとコメントが乖離していく

改善方法

  • 変数名、関数名などを工夫することで改善可能
    • 名前で意味や意図、役割を表すようにする
    • コードを読むだけで分かることはコメントに書かない

データ構造の二重化

縦、横、面積のデータ構造を持つコード例

Rectangle.cs
// 違反例
public class Rectangle
{
    public int Height { get; set; }
    public int Width { get; set; }
    public int Area { get; set; }
}

良くない点

  • 縦か横の長さが変化すると面積も変わる

改善方法

  • Area() は縦x横で面積を計算するメソッドに変更する
Rectangle.cs
// 改善例
public class Rectangle
{
    public int Height { get; set; }
    public int Width { get; set; }
    public int Area()
    {
        return Height * Width;
    }
}

終わりに

SOLID原則に続いてDRY原則をまとめました。
間違いや改善点あれば、ぜひ教えてください。
SOLID原則の記事は以下です。

  1. SOLID原則を勉強する その1~単一責任の原則 (SRP)~
  2. SOLID原則を勉強する その2~オープン・クローズド原則(OCP)~
  3. SOLID原則を勉強する その3~リスコフの置換原則(LSP)~
  4. SOLID原則を勉強する その4~インターフェース分離の原則(ISP)~
  5. SOLID原則を勉強する その5~依存性逆転の原則(DIP)~
7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?