直列つなぎ。 -とある発達障害者の記録

知識と知識を繋ぐためのblog。 広汎性発達と診断されました。ぜんぜん役に立ってないけど。月収13万円、家賃4万円で生活するひつじ人間。

C# 実装の隠蔽  隠蔽して実装すると複雑化するらしい。


このように、 クラスの実装方法を変更するたびに、利用側のコードまで修正する必要があると、 プログラムを作るのも保守するのも大変になります。

このような問題は、以下のように実装を隠蔽することで避けることができます。



コードA

using
System; // クラス定義 class Complex { // 実装は外部から隠蔽(privateにしておく) private double re; // 実部を記憶しておく private double im; // 虚部を記憶しておく public double Re(){return this.re;} // 実部を取り出す public void Re(double x){this.re = x;} // 実部を書き換え public double Im(){return this.im;} // 虚部を取り出す public void Im(double y){this.im = y;} // 虚部を書き換え public double Abs(){return Math.Sqrt(re*re + im*im);} // 絶対値を取り出す } // クラス利用側 class ConcealSample { static void Main() { Complex c = new Complex(); c.Re(4); // メソッドを通してオブジェクトの状態を変更 c.Im(3); Console.Write("|c| = {0}\n", c.Abs()); }
コードB

using
System; // クラス定義 class Complex { public double abs; // 絶対値を記憶しておく(外部からの読み出し・書き換えも可能) public double arg; // 偏角を記憶しておく(外部からの読み出し・書き換えも可能) // 実部・虚部を書き換え public void Set(double x, double y) { this.abs = Math.Sqrt(x*x + y*y); this.arg = Math.Atan2(y, x); } } // クラス利用側 class ConcealSample { static void Main() { Complex c = new Complex(); c.Set(4, 3); // クラス利用側のコードも修正が必要 Console.Write("|c| = {0}\n", c.abs); } }





このコードの実装方法を 「実部と虚部をメンバー変数に記憶しておく」方法から 「絶対値と偏角をメンバー変数に記憶しておく」方法に変更する場合、 以下のように、クラス利用側のコードに手を加える必要は一切ありません。

コードC

using System;

// クラス定義
class Complex
{
  // 実装は外部から隠蔽(privateにしておく)
  private double abs; // 絶対値を記憶しておく
  private double arg; // 偏角を記憶しておく

  // 実部を取り出す
  public double Re()
  {
    return this.abs * Math.Cos(this.arg);
  }

  // 実部を書き換え
  public void Re(double x)
  {
    double im = this.abs * Math.Sin(this.arg);
    this.abs = Math.Sqrt(x*x + im*im);
    this.arg = Math.Atan2(im, x);
  }

  // 虚部を取り出す
  public double Im(){return this.abs * Math.Sin(this.arg);}

  // 虚部を書き換え
  public void Im(double y)
  {
    double re = this.abs * Math.Cos(this.arg);
    this.abs = Math.Sqrt(y*y + re*re);
    this.arg = Math.Atan2(y, re);
  }

  public double Abs(){return this.abs;}  // 絶対値を取り出す
}

// クラス利用側
class ConcealSample
{
  static void Main()
  {
    Complex c = new Complex();
    c.Re(4); // クラス利用側は一切変更せず
    c.Im(3);
    Console.Write("|c| = {0}\n", c.Abs());
  }
}


コードD

↑のコードをAの様に実装し直してみた。
確かに利用側コードも変える必要があるみたいで。
でもその分のコードがどう見ても長くならざる負えないのでは・・・・。

利用側でシンプルにしようとした分、実装側が複雑化するカンジ。


using System;

// クラス定義
class Complex
{
    //隠蔽しない版
public double abs; // 絶対値を記憶しておく
 public double arg; // 偏角を記憶しておく





// 実部・虚部を書き換え
public double Abs(double x, double y)
{
this.abs = Math.Sqrt(x * x + y*y);

return this.abs;
}

public double Ags(double x, double y)
{
this.arg = Math.Atan2(y, x);
return this.arg;
}


    }
    public double Abs(double x, double y) {return Math.Atan2(y,x); }

}

// クラス利用側
class Program
{
    static void Main()
    {
        Complex c = new Complex();
      c.Set(4, 3); // クラス利用側のコードも修正が必要
   

        Console.Write("|c| = {0}\n", c.Abs());
    }
}




関連記事
スポンサーサイト

 C#

0 Comments

Leave a comment