|
インタフェースの使い方
|
o8qqqq
|
  |
データNo:180 |
2010年03月24日(Wed) 05:23 |
|
|
|
|
|
オブジェクト指向プログラミングに関して、VBAで出来ないこと->2.インタフェースのみの継承に問題がある
上記の記述に関して、インターフェースの使い方がおかしい気がしたので・・・
以下の記述があります。
1>以下のようにする必要があります。 2> Dim Obj1 As new Class1 3> Dim Obj2 As Class2 4> Set Obj2 = Obj1 5> Call Obj2.aaa 6> 7>■感想: 8>面倒くさい・・・。 9>(行数が長くなりソースが読みにくくなります。)
本来の記述方法であれば、以下のようになるのでは?
Dim Obj2 As Class2 Set Obj2 = new Class1 call obj2.aaa
問題点 1.必要のない変数「obj1」を宣言している。 2.使用するかどうかもわからん「Class1」のインスタンスを、宣言時に生成している。
あと、感想として「9>(行数が長くなりソースが読みにくくなります。)」とありますが、 逆のような気がするのですが?
以下、「Class2」がインターフェース 「Class1」、「Class3」、「Class4」、「Class5」が実装クラスとしての話
Dim Obj2 As Class2
select case InsSelect case 1 Set Obj2 = new Class1 case 3 set obj2 = new Class3 case 4 set obj2 = new Class4 case 5 set obj2 = new Class5 case else ' Err.Raise end select
call obj2.aaa
上記は、InsSelect変数ごとに、生成するインスタンスを変更し、「aaa」処理を実行する想定のコードです。
行数が長くなるとはとても思えないのですが? 逆に、行数を圧縮?していると思っているのですが、いかがでしょうか?
|
|
 |
Re:インタフェースの使い方
|
だるま
|
 |
データNo:181
|
2010年03月24日(Wed) 23:21
|
|
|
|
http://darumaexcel.uijin.com/aboutooa/vba_limit.html#implements の説明が悪すぎるのかも。
call obj2.aaa ができるのはいいのです。 (Class2のオブジェクト変数.aaa はできる)
Class1のオブジェクトをClass2としてしか使用しない場合はClass2型の変数を使ってプログラムできるのでいいのですが、場合によってはClass1のオブジェクトとして使用したい(Class1で定義したメソッドを使用したい)場合があります。その場合は当然Class1型の変数を使ってプログラムすると思いますが、そうするとClass2で定義したメソッドは呼び出せませんという話です。(どうしても呼びたかったらClass2型の変数に代入してから行う必要がありますが面倒だという話です。)
面倒と言う話ですが、個人的には余計な変数を定義するのが嫌です。なぜかというと、C/C++,Javaだと変数のスコープは{から}まで(メソッド内であっても{から}まで)なので、余計に変数が必要になっても、{}でくくれば外には影響しないので良いのですが、しかし、VBだとそんなのないから(メソッドの終わりまで有効になってしまうから)、余計な変数が追加されると、メソッドの終わりまでソースが読みにくくなってしまうためです。
|
|
 |
Re:インタフェースの使い方
|
o8qqqq
|
  |
データNo:182
|
2010年03月25日(Thu) 19:45
|
|
|
|
なるほど〜
私なら、Class1だけで使用したいメソッドがあった場合には、そのメソッドをインターフェースに含めてしまいます。 で、Class1で実装を行い、ほかの実装クラスでは空実装、もしくはErr.Raiseさせます。
もしくは、Class1用の特別関数用インターフェースを作ります。 インターフェースの多重継承はできるようなので。
以下は例です・・・
[SampleIF] Public Sub CallFunc()
end sub
[SampleIF2] Public Sub CallSpecialFunc()
end sub
[Imp1] Implements SampleIF Implements SampleIF2
Public Sub CallFunc() debug.print "ガチャピンでっす!" end sub
Public Sub CallSpecialFunc() debug.print "実はムックだったんですzo!" end sub
[Imp2] Implements SampleIF Public Sub CallFunc() debug.print "ガッチャマンでっす!" end sub
[main] Dim if as SampleIF Dim if2 as SampleIF2
Set if = new Imp1 Call if.CallFunc
'''set if2 = new Imp2 'ニューしなくてもOK? set if2 = if Call if2.CallSpecialFunc
'特別な関数を実装していない実装クラス Set if = new Imp2 Call if.CallFunc
実行環境を持っていないので確認はできませんが・・・ このような感じになるのでは?
ただ単に、実装クラスに対してCodingとしているのに変な感じがしただけです。
実装は、抽象的なものに対してしろ。と、教わったもので・・・
|
|
 |
Re:インタフェースの使い方
|
だるま
|
 |
データNo:183
|
2010年03月27日(Sat) 00:11
|
|
|
|
一応修正すると、 ==================================== [Imp1] Implements SampleIF Implements SampleIF2
Public Sub CallFunc() debug.print "ガチャピンでっす!" end sub
Public Sub CallSpecialFunc() debug.print "実はムックだったんですzo!" end sub ==================================== ↓ ==================================== [Imp1] Implements SampleIF Implements SampleIF2
Private Sub SampleIF_CallFunc() Debug.Print "ガチャピンでっす!" End Sub
Private Sub SampleIF2_CallSpecialFunc() Debug.Print "実はムックだったんですzo!" End Sub ==================================== となります。[Imp2]も同じです。 (また、なんかjavaやC++と違う部分が…。はぁ…。)
> 私なら、Class1だけで使用したいメソッドがあった場合には、そのメソッドをインターフェースに含めてしまいます。 > で、Class1で実装を行い、ほかの実装クラスでは空実装、もしくはErr.Raiseさせます。
それでもいいですが(※だるまも実際にそうしたこともあるかもしれない)、不要なメソッドはそもそも極力定義しない(空実装もErr.Raiseもしない)方が良いと思ってます。理由は動的テスト(単体テストなど)よりも静的テスト(コンパイルチェックなど)の方が圧倒的に楽なので、それによるチェックをより多くしたいためです。
> もしくは、Class1用の特別関数用インターフェースを作ります。 (略) > ただ単に、実装クラスに対してCodingとしているのに変な感じがしただけです。 > > 実装は、抽象的なものに対してしろ。と、教わったもので・・・
可能であれば、もう少し詳しく教えてほしいです。具体的には、モジュールの強度、結合度、ISO/IEC9126(JIS X 0129)、工数(経済的な面)などの面から、わかる範囲でいいので、メリットを教えてもらえないでしょうか(※デメリットも教えてください。でないとHPには載せられませんので。)
|
|
 |
Re:インタフェースの使い方
|
o8qqqq
|
  |
データNo:184
|
2010年03月27日(Sat) 03:42
|
|
|
|
>不要なメソッドはそもそも極力定義しない >(空実装もErr.Raiseもしない)方が良いと思ってます。
私もそう思います。 時間のない、やっつけ時にはやってしまうかも・・・ Err.Raiseさせるのは、最低限の防御策ですね。
なので、「もしくは」以降が本命です。
> ただ単に、実装クラスに対してCodingとしているのに変な感じがしただけです。 > 実装は、抽象的なものに対してしろ。と、教わったもので・・・
厳密には「なるべく」が抜けていましたね。 これはDIコンテナの影響ですかね。 オブジェクト間の関係を疎に保つ。とかなんとか...
インターフェースを引数にして、何かをする関数をつくると、実装クラスが何かに関係なく処理を行える。 実装クラスが何なのか、なんて知らないっす! 知りたくもないっす!! みたいなやつです。 Public Sub doSomeThing(ByRef if as Imp1) '何かやりマッスル end Sub
Dim if as SampleIF
Set if = new Imp1 call doSomeThing(if)
Set if = new Imp2 call doSomeThing(if)
こんな感じです。 doSomeThing関数は実装クラスがなんだろうが、インターフェースに準拠したものであれば、受け入れ、処理を実行します。 いちいち、クラス毎に何かを実行する関数等を作る必要がなくなります。 確かに、単体、そのインスタンスだけの処理を実行するのであれば、たいした意味はないのですが、連携する?場合に意味をなしてくると思っています。
Public Function DoValid(ByRef mif as MastIF _ ,ByRef tif as TranIF) 'キーの存在チェックをします end Function
Dim as mif as MastIF Dim as tif as TranIF Dim as blnRst as Boolean
set mif = new Book set tif = new BookSale blnRst=DoValid(mif,tif)
set mif = new Drug set tif = new DrugSale blnRst=DoValid(mif,tif)
という記述ができます。 DoValidはインターフェースに対して実装がなされています。 実装クラスが本だろうが、薬だろうが気にしません。
>可能であれば、もう少し詳しく教えてほしいです。 >具体的には、モジュールの強度、結合度、ISO/IEC9126(JIS X 0129)、 >工数(経済的な面)などの面から、わかる範囲でいいので、 >メリットを教えてもらえないでしょうか
上記がその答えのつもりなのですが、「モジュールの強度、結合度、ISO/IEC9126(JIS X 0129)」とかは何を言っているのか分かりません。 所詮は、趣味でやっている素人プログラマー?なので底が見えてしまいますね... 多分「結合度」に関していえば、なるべく軽くするべし!!ってなるんでしょうか。
まあ、私の言いたかったことはインターフェースがあれば最低限OOP出来るだろ! それにインターフェースを使った実装方法の恩恵を受けられるだろ!
それにつけてもStaticな変数、関数がないのがいたいっすね〜 これがあれば、もう少しましなことが出来るとは思うのですが。
まあ、私の発言は気にしないでください。すいませんでした。
|
|
 |
Re:インタフェースの使い方
|
だるま
|
 |
データNo:185
|
2010年03月27日(Sat) 13:58
|
|
|