SSブログ

「オブジェクト指向プログラミング」について(その3) [プログラミング]

http://himakou.blog.so-net.ne.jp/2012-08-22 の続き

博士: 前回は,実際にVBで書いたプログラムを比較することで,「オブジェクト指向プログラミング」の雰囲気を味わってもらったつもりだが,どうであったか?

助手: 確かに,「オブジェクト指向プログラミング」のセンスを取り入れることで,「オブジェクト」に固有の手続きに関するプログラミングを全体的な手続きの「流れ」から分離し,プログラム全体の見通しをよくする感じについてはよくわかった気がします。しかし,前回のプログラムで困ったことに気づきました。

博士: なんじゃと?助手: 実験してみたところ,ワタシが書いた<例1>と比べて,博士の<例2>や<例3>は10倍も余計に時間がかかることがわかりました。「オブジェクト指向プログラミング」って,かえって効率が悪いんじゃないんですか?

博士: なんだ,そのことか。ワシの書いた<例2>や<例3>は確かに遅い。しかし,これは「オブジェクト指向プログラミング」そのものに問題があるわけではないぞ。

助手: じゃあどこに問題があるのでしょうか?

博士: 連載記事の冒頭で強調したとおり,「オブジェクト指向プログラミング」は単なるプログラミング「手法」の一つに過ぎない。「オブジェクト指向プログラミング」はプログラム全体の見通しをよくすることに資するものの,ロジック選択の良し悪しに影響を与えるものではない。<例2>や<例3>が遅いのは,ロジック選択がまずかったということじゃ。

助手: (うれしそうに)ということは,ワタシが書いた<例1>の方がロジック的に優れていたということですね♪

博士: はしゃぐでない。<例2>や<例3>は「オブジェクト指向プログラミング」の具体的な恩恵を目に見える形で理解してもらうことを主眼としたものじゃ。確かに,素数探索の問題では素数のリストをポチポチ育てていくのは効率が悪く,<例1>のようにエラトステネスのふるいで一気に作ってしまう方が効率がよい。というわけで,<例1>を「オブジェクト指向プログラミング」的なセンスで書き変えてみたぞ。これならどうじゃ?

<例4>
    Sub Main()
        Dim t As Double = Timer
        Dim x As Integer = 100000
        Dim nmax As Integer = 100000000
        '**
        Dim p As New PrimeNumber(nmax)
        Debug.Print("{0}", Timer - t)
        MsgBox(x & "番目の素数は" & p(x - 1) & "です")
    End Sub

    Public Class PrimeNumber
        Private IsNotPrimeNumber() As Boolean
        Public Sub New(ByVal nmax As Integer)
            ReDim IsNotPrimeNumber(nmax)
            IsNotPrimeNumber(0) = True
            IsNotPrimeNumber(1) = True
            Dim i As Integer
            For i = 2 To nmax
                If Not IsNotPrimeNumber(i) Then
                    Dim j As Integer = 2
                    Do While i * j <= nmax
                        IsNotPrimeNumber(i * j) = True
                        j += 1
                    Loop
                End If
            Next
        End Sub
        Default Public ReadOnly Property Item(ByVal n As Integer) As Integer
            Get
                Dim i As Integer = 0
                Do
                    Do While IsNotPrimeNumber(i)
                        i += 1
                    Loop
                    n -= 1
                    If n < 0 Then
                        Return i
                    End If
                    i += 1
                Loop
            End Get
        End Property
    End Class


助手: 確かに計算時間は<例1>と同じくらいになりました。その代わり,NewとかPropertyとか見慣れないキーワードが使われてますね。

博士: Newはすでに登場しているぞ。とはいっても,<例2>や<例3>でクラスのインスタンスを定義する際におまじないのように登場しているだけだったが。<例4>では,PrimeNumberクラスにNewメソッドが新たに定義されておるな。

助手: <例2>や<例3>のおまじないのようなNewと<例4>で定義されたNewメソッドには関係があるんですか?

博士: 大ありじゃ。<例2>のNewは,ListクラスのNewメソッドを呼び出しているに過ぎん。また<例3>のNewは,ListクラスからPrimeNumberクラスに継承されたNewメソッドを呼び出しているわけじゃ。このあたりは,クラス定義の説明を聞いてからでないとわかりづらいとは思うが,いずれ腹にストンと落ちるであろう。

助手: Propertyについてはいかがでしょうか?

博士: Propertyとはデータの読み書きを主目的とする関数を示すキーワードであり,<例4>ではPrimeNumberクラスにItemという読み取り専用のプロパティが定義されておる。Itemプロパティにはインデックス番号を指定するようになっており,PrimeNumberクラスのpインスタンスに対してp.Item(i)またはp(i)とすることで,あたかもi番目の配列要素を指定するかのようにi番目の素数が得られる作りになっておる。

助手: p(i)はp.Item(i)と同じ意味なんですか?

博士: そうじゃ。Propertyの定義にDefaultというキーワードがついていることで,こうした配列ライクな表記が可能になるのじゃ。単なる表記上のアヤといえばそれまでだが,このおかげで全体的な手続きの「流れ」が

    Sub Main()
        Dim t As Double = Timer
        Dim x As Integer = 100000
        Dim nmax As Integer = 100000000
        '**
        Dim p As New PrimeNumber(nmax)
        Debug.Print("{0}", Timer - t)
        MsgBox(x & "番目の素数は" & p(x - 1) & "です")
    End Sub


と,非常に直感的な形に書けている点に注目してほしい。これも「オブジェクト指向プログラミング」の恩恵と言えよう。

助手: 確かにおっしゃるとおりです。PrimeNumberクラスが<例3>と同様に素数のリストのようにみえます。しかも,Dim p As New PrimeNumber(nmax)としただけで,pの中にnmax以下の素数リストが完成しているなんて!!

博士: (得意げに)そうじゃろそうじゃろ。実は,PrimeNumberクラスの実態は<例1>と同じくBoolean型の配列なのだが,そうと悟られないようにクラス設計を工夫したつもりじゃ。

助手: よくわかりました。ひとえに「オブジェクト指向プログラミング」といっても,ロジックその他の設計によってさまざまなプログラムになるということですね。

博士: そのとおりじゃ。何度も繰り返すが,「オブジェクト指向プログラミング」は単なるプログラミング「手法」の一つに過ぎない。しかし,「オブジェクト指向プログラミング」によってプログラム全体の見通しがよくなれば,バグの発生が抑えられたり,プログラムの読みやすさが格段に向上するため,それだけコアの設計に専念できるという恩恵が大きいのじゃ。

助手: 何度も恐れ入りました。。(その4に続く)
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。