多重継承とUMLの導入
Figureクラスで図形描画を仮想関数を用いて演習を行ったが、 課題のテーマとした色を用いたクラスを実装する場合には、様々な方法がある。 レポート課題と取り組まれている中とは思うけど、次のテーマの多重継承の導入として総括する。
また、後半は、UMLの基本を説明する。
色付き図形の実装方法
最初の基本となるFigure(FigureColor)が、色情報を持つ方法。 しかしこの方法は、基底クラスから異なるデータ構造として定義することになるため、 全体のプログラムを書き換えることになる。 この場合、すでにFigure,FigureBox…といったクラスでプログラムを 書いている人がいたら、全面的なプログラム修正が必要となるため、 混乱の元になる。
(( FigureColorが色情報を持つ基底クラス )) class FigureColor { private: int color ; public: FigureColor( int c ) : color( c ) { } virtual void draw( int , int ) = 0 ; } ; // FigureColorから派生 class FigureColorBox : public FigureColor { private: int width , height ; public: FigureColorBox( int w , int h , int c ) { : FigureColor( c ) , width( w ) , height( h ) {} virtual void draw( int , int ) { } } ;
授業で説明した、FigureBoxからFigureBoxColorを派生する方法は、 既存のプログラムの延長で機能を追加できる。このため、既存のコードの 有効利用ができるのが利点。 しかし、FigureBox以外に、FigureCircle,FigureStar,FigureTriangle….といった 様々な派生がすでに存在する時は、色に関するコードが後付なので、 色に関するクラスをさらに作る場合は、色の設定処理が洗練された書き方にできない。
(( Figure→FigureBox→FigureBoxColor )) class Figure { (略) } ; class FigureBox : public Figure { (略) } ; class FigureBoxColor : public FigureBox { private: int color ; public: virtual void draw( int x , int w ) { GWsetpen( ... , color , ... ) ; // ださい FigureBox::draw( x , y ) ; } } ;
多重継承
前のFigureBoxColorの例は、色のクラスが後付なので、色に関する処理が複雑であったとして、 その処理を隠蔽化するにはどうすればよいか? 一つの方法が、多重継承である。
class Figure { (略) } ; // 色を扱うクラス class Color { private: int color ; public Color( int c ) ; void setcolor() { GWsetcolor( ... , color , ... ) ; } } ; // 色無しのクラスはそのまま使える class FigureBox : public Figure { (略) } ; class FigureBoxColor : public FigureBox , public Color { public: FigureBoxColor( int w , int h , int c ) : FigureBox( w , h ) , Color( c ) {} virtual void draw( int x , int y ) { setcolor() ; // Colorのメソッドを使う FigureBox::draw( x , y ) ; } } ;
ただし多重継承は以下の理由から、実装が複雑化することから、Javaなどの言語では別の方法を用いる。
- 継承は、派生したクラスのデータが基底クラスの後ろに繋がる形で実装される。 データ領域の先頭部分は基底クラスのデータ領域であり、基底クラスの参照は極めて単純。 しかし、多重継承を認めると、データ領域の後ろに派生データを追加する方法では、 途中に別の基底クラスのデータ領域を挟み込む形になるため、基底クラスを参照することが複雑になる。
- また、基底クラスに同名のメソッドがあった場合、派生クラスでのメソッド呼び出しでどちらを呼び出すべきか、曖昧になる。
- さらに、ダイヤモンド継承があると、基底クラスのデータが2重化する可能性がある。
(( ダイヤモンド継承 )) 動物クラス[誕生日] / \ 鳥クラス[羽] 哺乳類クラス[手] \ / カモノハシ // 鳥クラスは要素として[誕生日,羽]を持つ // 哺乳類クラスは、[誕生日,手]を持つ // カモノハシクラスは、[誕生日,羽,誕生日,手]を持つ???
UML
UML(Unified Modeling Language)とは、オブジェクト指向で、データ構造や処理の流れを図で表現するための手法として 考えられた。
例えば、処理の流れを図示する場合のフローチャートは、初心者でも分かりやすい。 しかし、長方形のマスの中に複雑な処理を記入するのは困難となる。 改良版として、PADという記法もあるが、あまり普及していない。
歴史的に見れば、 ランボーの提唱したオブジェクトモデル化技法(OMT)、 ブーチがオブジェクト指向設計(OOD)でのBooch法、 ヤコブソンのオブジェクト指向ソフトウェア工学(OOSE)の考え方を元に、 UML(統一モデリング言語)が策定された。
UMLでの図の表現は、データ構造を表現するクラス図、コンポーネント図、オブジェクト図、パッケージ図などがあり、 一方で処理の振舞いを記述する、アクティビティ図、ユースケース図、状態遷移図、相互作用図、シーケンス図などがある。 詳しくは次週の講義にて、説明。
UPKIオープンドメイン証明の申請(機構版)
学術研究機関を対象とした、無償のSSL認証キーの発行サービスの申請のTSVファイル生成だが、 機構管理下となったので、手順が一部変更となった。 手順が長いので、肝心な所は記載しないが、その入力などの内容をメモ。 最終的に、電子情報工学科のTSVファイルと、緊急連絡システム用のTSVファイルを作った。
# mkdir /etc/apache2/ssl.key/ # cd /etc/apache2/ssl.key/ # cp 大きいファイル1 randfile1.txt # cp 大きいファイル2 randfile2.txt # cp 大きいファイル3 randfile3.txt # openssl genrsa -des3 -rand randfile1.txt:randfile2.txt:randfile3.txt 2048 > iris.key Enter pass phrase: [passphrase] Verifying - Enter pass phrase: [passphrase] # lv iris.key -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,xxxxxxxxx : -----END RSA PRIVATE KEY----- # openssl req -new -key iris.key -sha1 -out iris.csr Enter pass phrase for maisy.key: [passphrase] Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:. Locality Name (eg, city) []:Academe Organization Name (eg, company) [Internet Widgits Pty Ltd]:National Institute of Technology Organizational Unit Name (eg, section) []:Fukui College Common Name (eg, YOUR name) []:www.ei.fukui-nct.ac.jp Email Address []:. Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:. An optional company name []:. maisy:/etc/apache2/ssl.key# lv iris.csr -----BEGIN CERTIFICATE REQUEST----- : -----END CERTIFICATE REQUEST----- maisy:/etc/apache2/ssl.key# openssl req -noout -text -in iris.csr Certificate Request: Data: Version: 0 (0x0) Subject: C=JP, L=Academe2, O=Fukui National College of Technology, OU=Electronics and Information Department, CN=www.ei.fukui-nct.ac.jp Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): https://certs.nii.ac.jp/cgi-bin/tsvtool.cgi TSV作成ツール:発行申請TSV ・CSRファイルから iris.csr [CSR送信] CSR 主体者DN CN=www.ei.fukui-nct.ac.jp,OU=... サーバFQDN www.ei.fukui-nct.ac.jp dNSName なし 加入者Email 自分のメール 加入者氏名 斉藤 徹 加入者所属 福井工業高等専門学校電子情報工学科 ソフトウェア名等 Apache 2.4.6 [完了] [ダウンロード] issue-YYYYMMDD.tsv
実際に鍵を登録
UPKIの事務局に、issue-YYYYMMDD.tsv を送ったら、 鍵を入手するための「UKPI-ODCert]Webサーバ証明書発行受付通知」なるメールが 送られてきた。指定されたURLをアクセスして、サーバ証明書を受け取る。 ファイル名は、"サーバFQDN.cer"であった。(Apacheへの登録では"*.crt"に直す)
これに加えて、別途 "nii-odca3sha1.cer" を入手しておく。
このままだと、Webサーバ起動時にパスフレーズを聞かれるので、
# openssl rsa -in iris.key -out iris-passphrase.key : Enter pass phrase for iris.key: [passphrase]
# cd /etc/apache2/ssl.key # mv ...PATH.../サーバFQDN.cer ./iris.crt # vi /etc/apache2/sites-enabled/100-default-ssl : SSLCertificateFile /etc/apache2/ssl.key/iris.crt SSLCertificateKeyFile /etc/apache2/ssl.key/iris-passphrase.key SSLCertificateChainFile /etc/apache2/ssl.key/nii-odca3sha1.crt : # /etc/init.d/apache2 restart