本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第3章 SOLID原則 · レッスン22

開放閉鎖の原則(O)

ブラウザで完結

導入

Open/Closed Principle——「拡張に対して開き、修正に対して閉じる」。新しい種類を追加するとき、既存のコードを書き換えずに足すだけで済む設計を目指します。

図解

flowchart TB
    subgraph Before["修正に弱い"]
        SW["if 種類==円 … else if 四角 …<br/>新種類のたびに if を書き換える"]
    end
    subgraph After["拡張に強い"]
        I["interface Shape.Area()"]
        I --> C["Circle"]
        I --> R["Rectangle"]
        I --> T["Triangle(足すだけ)"]
    end
    Before -->|多態性で置き換え| After

サンプル

// ✅ 新しい図形は「クラスを足すだけ」。合計処理は一切変更不要
IShape[] shapes = { new Circle(5), new Rectangle(4, 3) };
double total = shapes.Sum(s => s.Area());
Console.WriteLine($"合計面積: {total}");

interface IShape { double Area(); }

class Circle : IShape
{
    private double _r;
    public Circle(double r) { _r = r; }
    public double Area() => 3.14159 * _r * _r;
}

class Rectangle : IShape
{
    private int _w, _h;
    public Rectangle(int w, int h) { _w = w; _h = h; }
    public double Area() => _w * _h;
}
// Triangle を足したくなっても、上の合計処理は書き換え不要
  • 新機能の追加が「既存コードの修正」ではなく「新クラスの追加」で済むようにする
  • インターフェース+多態性がこの原則の主な実現手段
  • ifの羅列を増やし続ける設計は、この原則に反する

演習

IShape[] shapes = { new Square(4) };
Console.WriteLine(shapes.Sum(s => s.Area()));   // 16

// TODO: IShape(Area())を実装する Square クラス(一辺 side)を定義してください
//       (既存の合計処理を変えずに“足すだけ”で機能追加できることを体感)
interface IShape { double Area(); }
___
  • 期待される出力: 16
ヒント1を見る

class Square : IShape { private int _s; public Square(int s) { _s = s; } public double Area() => _s * _s; }

ヒント2を見る

合計処理はIShapeに依存しているので、実装を足すだけで動きます

まとめ

  • 開放閉鎖の原則:拡張に開き、修正に閉じる
  • 新種類は「クラスを足すだけ」にする
  • インターフェース+多態性が実現手段

次回: 親の代わりに使える「リスコフの置換原則」です。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。