内部でStaticな変数に依存しない

アンチパターンのひとつで、オブジェクトの処理内にStaticメンバーへ依存してはいけないというものがあります。

大したことはないのですが。例えば以下のようなある種のグローバル変数があって

public class GlobalValiables
{
    public static bool InternalSwitch { get; set; }
}

次のような処理内で利用されていたとします。

public class MyClass
{
    public int Execute()
    {
        if(GlobalValiables.InternalSwitch) // 内部でstatic変数を参照
        {
            return 1;
        }
        else
        {
            return 2;
        }
    }
}

InternalSwitchが別のクラスのによって書き換えられている場合、利用者は意図しない結果を受け取ることになります。したがって、たいていの場合でこのような処理を書くべきではありません。

また、クラスを利用する時に別のstaticメンバーが事前に初期化されていないと実行時にエラーが発生する場合には、単体テストの実行が妨げられたりするケースもあります。

このような場合、そういった以下の3つの方針で変数の依存を外から指定するように変更しstatic変数の依存を排除できます。

  • 処理開始時の引数で条件を指定する
  • プロパティによって条件を指定する
  • コンストラクタによって条件を指定する
// 引数によって条件を指定する
public class MyClass_Csae1
{
    public int Execute(bool mode) 
    {
        //...
    }
}

// プロパティによって条件を指定する
public class MyClass_Case2
{
    public bool Mode { get; set; } = true;

    public int Execute()
    {
        if(this.Mode)
        {
            //...
        }
        else
        {
            //...
        }
    }
}

// コンストラクタで指定する
public class MyClass_Case3
{
    public MyClass_Case3(bool mode){ /* ... */ }

    public int Execute(){ /*...*/ }
}

ただ、こう言ったものが大量にあるとオブジェクトの生成処理の記述もなかなか負担になるため、下位のモジュールではstatic依存を除外し、上位のモジュールではstatic依存を限定的に利用するなどレイヤーによって利用する・しないを分割する方針をとるケースが多いように思います。