時代に翻弄されるエンジニアのブログ

ゲームプログラマをやっています。仕事やゲームや趣味に関してつらつら書きたいと思います。

SOLID原則 ゲームで使える OCPの原則

f:id:tkymx83:20190120003731p:plain:w1000

こんにちは、ゲーム開発でクラス間の依存性に困っている人はいませんか?

僕は最近かなり困っています。依存性の強い状態では追加実装や改修が入ったときにいろいろなものに影響が出てきます。

今回はそんなときに使えずOCPの原則(オープン・クローズの原則)についてゲームでどう使えるかを解説したいと思います。

「OCPの原則」とは

新しい機能を作るときに必要のないクラスに変更が入ることはありませんか?

OCPの原則は拡張に開いていて・修正に閉じている設計のことを言います。

拡張に開いているとは、拡張するときに他の要素の変更することなく追加が用意であることを表しています。

修正に閉じているというのは、修正するときにいろいろな箇所に変更をするのではなく、一箇所の変更のみで済むことを表しています。

このようなプロジェクトでは、新しい機能やバグの修正でのエンバグを最小限に留めることができます。

拡張が難しい状態って?

例えばアクションゲームを作っていて状態異常の実装をしたとします。

f:id:tkymx83:20190120003745p:plain:w1000

何も考えなければ、キャラクタが状態異常管理クラスを持っていて、新しい状態異常がその管理クラスに入っていることを想像すると思います。

この場合2つの事象が起きます。

  • 新しい状態異常をついか追加する場合は状態異常管理クラスが肥大化する。
  • 敵と味方で状態異常管理方法を変更する場合キャラクタクラスが肥大化する。

つまりは、拡張や修正する場合に他のコードも修正する必要があるということです。

この設計の良くないところは上から下に依存が発生していることです。この依存性を反転させることでこの問題は解決します。

どうやって依存性を反転させるの?

それは、各要素のつなぎをインタフェースを使って抽象化して上げることです。

f:id:tkymx83:20190120003800p:plain:w1000

抽象化することで、状態異常管理クラスは状態異常の種類によらずに状態異常を管理できます。

そして新しい状態異常を追加するときも、インタフェースを継承したクラスを追加するだけで済むのです。

ここで重要なことは、画像のように各モジュールがその中で依存性が閉じていて、新しいモジュールを追加することで拡張ができるということです。

まとめ

このように 「OCPの原則は」拡張しやすく、修正の影響範囲が少ない設計です。

依存が発生するのは仕方ないことですが、その依存性をインタフェースを使って反転させることで、このような柔軟な設計ができるということです。

ここからは体験談ですが

インタフェースを挟むことでコード自体は増えて見づらくなるとはじめは思っていました。ですが、実際運用をしていると、状態異常のように新しい要素がどんどん追加されるものにとってこの設計はかなりの力は発揮してくれると実感しました。