BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース C#でSOLIDにする

C#でSOLIDにする

ブックマーク

原文(投稿日:2014/05/23)へのリンク

Autonomous Solutions Inc.のソフトウェア開発者Brannon B. King氏は2014年5月MSDN MagazineC#でSOLIDの原則に反することの危険性と題した記事を公開した。著者は、開発者のミスでC#コードがSOLIDの原則を破ることで、拡張または維持することがより難しくなる概要を説明した。

King氏は、カウンターコードのサンプルとすべてのSOLIDの原則のためのアドバイスを提供したが、簡潔にするためにオープン・クローズドの原則(OCP)に関係した一部を抽出した。OCPでは、"ソフトウェア エンティティ (クラス, モジュール, 関数など)は、拡張のためにオープンでだが、変更にはクローズであるべき"と位置づけている。King氏によると、以下のコードはOCPを破壊する。

void DrawNerd(Nerd nerd) {
   if (nerd.IsSelected) DrawEllipseAroundNerd(nerd.Position, nerd.Radius);
   if (nerd.Image != null) DrawImageOfNerd(nerd.Image, nerd.Position, nerd.Heading);
   if (nerd is IHasBelt) // a rare occurrence
      DrawBelt(((IHasBelt)nerd).Belt);
   // Etc.
}

なぜなら“あなたが、顧客が新しいものを表示するニーズがあるたびにこのメソッドを変更する必要がある”ため、代わりに描画するための汎用的なプロシージャーを提案する:

readonly IList<IRenderer> _renderers = new List<IRenderer>();
void Draw(Nerd nerd) {
   foreach (var renderer in _renderers)
    renderer.DrawIfPossible(_context, nerd); }

このアイディアは

…よく知られたインターフェイスを実装した描画クラス(または描画に関するクラス)を書きます。レンダラーは、入力に応じてなにを書くかを判断するために、賢くある必要があります。たとえば、ベルトを描画するコードは、インターフェイスをチェックして、必要に応じて進める“ベルトレンダラー”に移動することができます。

OCPを破壊するその他の例は、継承クラスを参照するクラスである。

class Nerd {
public void DanceTheDisco() {
if (this is ChildOfNerd)
throw new CoordinationException("Can't");
   ...
}

}
class ChildOfNerd : Nerd { ... }

著者のアドバイスは“基底クラスを直接継承先から参照してはならない。”ということである。この問題はピアクラスで表すことができる:

class NerdsInAnArc {
public bool Intersects(NerdsInAnLine line) {
    ...
   }
   ...
}

King氏は説明する:

Arcsとlinesは一般的にはオブジェクト階層でピアです。相互について親密に知るべきではなく、それらの詳細は、最適な共有アルゴリズムで必要になることがあります。他を変更することなく、自由に変更できるようにしておきます。これはまた、単一責務の原則に違反します。あなたはarcsをストアしますか、それともそれを分析しますか?独自のユーティリティクラスに分析操作を含めます。

小さなプロジェクトでは、SOLIDの原則を厳格に適用する必要はないかもしれないが、大きなコードベースでは、さらに重要になり、“スパゲッティ”コードを避けることは非常に望ましい。

この記事に星をつける

おすすめ度
スタイル

BT