ホーム » スタッフ » 斉藤徹 » 講義録 » オブジェクト指向 » 隠蔽化の課題(複素数クラスを例に)

2015年4月
« 3月   5月 »
 1234
567891011
12131415161718
19202122232425
2627282930  

最近の投稿(電子情報)

アーカイブ

カテゴリー

隠蔽化の課題(複素数クラスを例に)

前回の隠蔽化の話を受け、実際のプログラムの例を課題に説明。 複素数クラスを(実部,虚部)で実装した後に、(絶対値,偏角)に直したら…

基本プログラム(実部と虚部)

複素数を扱うクラスを作るのであれば、基本的には以下の様なコードとなるだろう。 複素数どうしの簡単な加算・乗算を記載する。

class Complex {
private:
   double re , im ;
public:
   Complex( double x , double y ) {
      re = x ;
      im = y ;
   }
   // 上記コンストラクタは、以下のようにも書ける。
   // Complex( double x , double y )
   // :   re( x ) , im( y )
   // { メンバ以外の初期化... }
   void print() {
      printf( "%lf+j%lf¥n" , re , im ) ;
   }
   void add( Complex &z ) {
      re = re + z.re ;
      im = im + z.im ;
   }
   void mul( Complex &z ) {
      double x = re * z.re - im * z.im ;
      double y = re * z.im + im * z.re ;
      re = x ;
      im = y ;
   }
} ;
int main() {
   Complex a( 1 , 2 ) ;
   Complex b( 2 , 3 ) ;
   a.add( b ) ;
   a.print() ;
   a.mul( b ) ;
   a.print() ;
   return 0 ;
}

Complexクラス内部をリファクタリング

しかし、前述プログラムでは、mul()メソッドは、add()メソッドよりは、 複雑なものとなっている。 しかし、複素数の乗算は、(絶対値と偏角)を用いれば、絶対値の乗算・偏角の加算で 処理は簡単に記述できる。そこで、クラス内部を乗算と偏角で処理をするように変更してみる。

class Complex {
private:
   double r , th ;
public:
   Complex( double x , double y ) {
      r = sqrt( x*x + y*y ) ;
      th = atan2( y , x ) ; // atan2は象限を考慮してくれる
   }
   void print() {
      printf( "%lf ∠ %lf¥n" , r , th / 3.141592 * 180.0 ) ;
   }
   void add( Complex &z ) {
      // ここは面倒な式になっちゃう
   }
   void mul( Complex &z ) {
      r  = r  * z.r ;
      th = th + z.th ;
   }
} ;
int main() {
   Complex a( 1 , 2 ) ;
   Complex b( 2 , 3 ) ;
   a.add( b ) ;
   a.print() ;
   a.mul( b ) ;
   a.print() ;
   return 0 ;
}

ここで重要なポイントは、2つめの絶対値∠偏角のプログラムの呼び出し側 main() は、 1つめのプログラムとまるっきり同じである。

このように、オブジェクト指向の隠蔽化を行っていれば、当初のクラス設計が悪くて後で変更 したくなった場合、利用者側からの見た目の動作を変更せずに、内部のデータ構造や処理メソッドを 変更が可能となる。 このように、利用者側からの見た目を変更せずに処理の内部を変更すること、 リファクタリング と呼ぶ。これにより、プログラムの不備や問題点があっても、積極的にプログラムを 改良できることから、不備の少ない安全なプログラムを作れるようになる。

隠蔽化の課題

以上の2つのプログラムで複素数の計算メソッド、加算(add),除算(sub),乗算(mul),除算(div)…その他を (実部,虚部)、(絶対値,偏角)で記載し、適切に記述をすれば、呼び出し側main()を まるっきり同じものにできることを通して、隠蔽化についてレポートにまとめよ。

レポートでは、以下の点を記載すること。(レポートは、本科中間試験の頃までに提出が望ましい)

  • 2つの方式でのプログラム例
  • 上記プログラムに対する説明
  • 上記プログラムが正しく動作していたことが判る結果
  • この課題から判る考察