「オブジェクト指向プログラミング」について(その2) [プログラミング]
http://himakou.blog.so-net.ne.jp/2012-08-21 の続き
助手: 博士,前回は「オブジェクト指向プログラミング」を次のように踏み込んで定義しましたが,もう少し具体的に教えてもらえませんか。
「オブジェクト指向プログラミング」とは,全体的な手続きの「流れ」を重視してきた従来のプログラミングと異なり,処理の「オブジェクト(=対象物)」を重視することによって,「オブジェクト」に固有の手続きに関するプログラミングを全体的な手続きの「流れ」から分離することを目指すことで,プログラム全体の見通しをよくするプログラミング「手法」である。
博士: よしよし。それではVisual Basic 2008(以下「VB」)を用いて,具体的にプログラムを書き分けてみようかの。たとえVBが不慣れであっても,プログラムを比較することで,「オブジェクト指向プログラミング」の雰囲気を味わってもらいたい。
助手: よろしくお願いします。博士: お題は「小さい方から100000番目の素数を見つけ出すプログラム」じゃ。キミならどう書くかな?
助手: とりあえずこんな感じでいかがでしょうか。IsNotPrime(i)はBoolean型の配列であり,iが素数でない場合にTrueとなるようなエラトステネスのふるいを意味します。答えは「1299709」と出ました。
<例1>
博士: 有名なエラトステネスのふるいじゃな。小さい方から順に発見した素数の倍数をつぶしていくというものだが,必要なふるいのサイズがnmax = 100000000で十分と決めつけているのには目をつぶるとしても,これは全体的な手続きの「流れ」を重視したプログラミングの典型例と言えよう。
助手: 全体的な手続きの「流れ」を重視したプログラミングが何かいけないんでしょうか。
博士: いけないとまでは言っとらん。ただし,「オブジェクト指向プログラミング」的なセンスでこう書くこともできる。
<例2>
助手: なるほど。素数のリストを徐々に増やしていくやり方ですね。
博士: 「オブジェクト指向プログラミング」的なセンスを取り入れたことが伝わるかのう。どういうことかというと,素数のリストを重要な「オブジェクト」と捉え,これをList(Of Integer)クラスのPrimeNumberというインスタンス(=変数)で表現したのじゃ。ListクラスはMicrosoftによって提供されており,後から要素を追加していくことができる便利なクラスである。はじめは空っぽだったPrimeNumberインスタンスに発見した素数を追加していくことで素数のリストを育てていくイメージじゃ。
助手: PrimeNumber.Add(i)という部分で実際に素数を追加しているわけですね。それにしても,素数のリストをFor Each文で使うあたりがオシャレですねえ。
博士: (得意げに)そうじゃろそうじゃろ。とはいえ,Listクラスという強力なクラスを使うことさえ思いつけば,「オブジェクト指向プログラミング」などと大きく出る話ではない。
助手: そうすると,「オブジェクト指向プログラミング」にはまだ先があると?
博士: そうじゃ。<例2>をさらに「オブジェクト指向プログラミング」的に書き直すとこうもできる。
<例3>
助手: 基本的なロジックは変わっていないようですが,ClassとかInheritsとか見慣れないキーワードが出てきますねえ。
博士: Public Class PrimeNumber : Inherits List(Of Integer)の意味は,List(Of Integer)クラスを継承するPrimeNumberクラスを自ら定義するということじゃ。PrimeNumberクラスには,AddNextPrimeというメソッドが定義されているが,このメソッドのおかげで全体的な手続きの「流れ」が
と,非常に直感的な形に書けている点が「オブジェクト指向プログラミング」の最大の恩恵じゃ。これならVBがわからなくても,全体的な手続きの「流れ」が一目瞭然ではないかな?
助手: 確かにおっしゃるとおりです。これならPrimeNumberクラスの定義をよく読まなくても,PrimeNumberクラスのpインスタンスに対して,p.AddNextPrime()で素数をポチポチ追加している雰囲気がよくわかります。かといって,PrimeNumberクラスの定義も決してわかりづらいわけではなく,全体としてプログラムが読みやすくなった気がします。
博士: そのとおりじゃ。素数リストという「オブジェクト」をPrimeNumberクラスとしてキャラ立ちさせ,エラトステネスのふるいに素数を追加するという固有の手続きをPrimeNumberクラスのAddNextPrimeメソッドとして切り出すことで,全体的な手続きの「流れ」の見通しがよくなったということじゃな。
助手: 恐れ入りました。。(その3に続く)
助手: 博士,前回は「オブジェクト指向プログラミング」を次のように踏み込んで定義しましたが,もう少し具体的に教えてもらえませんか。
「オブジェクト指向プログラミング」とは,全体的な手続きの「流れ」を重視してきた従来のプログラミングと異なり,処理の「オブジェクト(=対象物)」を重視することによって,「オブジェクト」に固有の手続きに関するプログラミングを全体的な手続きの「流れ」から分離することを目指すことで,プログラム全体の見通しをよくするプログラミング「手法」である。
博士: よしよし。それではVisual Basic 2008(以下「VB」)を用いて,具体的にプログラムを書き分けてみようかの。たとえVBが不慣れであっても,プログラムを比較することで,「オブジェクト指向プログラミング」の雰囲気を味わってもらいたい。
助手: よろしくお願いします。博士: お題は「小さい方から100000番目の素数を見つけ出すプログラム」じゃ。キミならどう書くかな?
助手: とりあえずこんな感じでいかがでしょうか。IsNotPrime(i)はBoolean型の配列であり,iが素数でない場合にTrueとなるようなエラトステネスのふるいを意味します。答えは「1299709」と出ました。
<例1>
Sub Main() Dim t As Double = Timer Dim x As Integer = 100000 Dim nmax As Integer = 100000000 '** Dim IsNotPrime(nmax) As Boolean IsNotPrime(0) = True IsNotPrime(1) = True Dim i As Integer For i = 2 To nmax If Not IsNotPrime(i) Then Dim j As Integer = 2 Do While i * j <= nmax IsNotPrime(i * j) = True j += 1 Loop End If Next '** Dim counter As Integer = 0 For i = 0 To nmax If Not IsNotPrime(i) Then counter += 1 If x = counter Then Debug.Print("{0}", Timer - t) MsgBox(x & "番目の素数は" & i & "です") Exit Sub End If End If Next Debug.Print("{0}", Timer - t) MsgBox(x & "番目の素数は" & nmax & "よりも大きいです") End Sub
博士: 有名なエラトステネスのふるいじゃな。小さい方から順に発見した素数の倍数をつぶしていくというものだが,必要なふるいのサイズがnmax = 100000000で十分と決めつけているのには目をつぶるとしても,これは全体的な手続きの「流れ」を重視したプログラミングの典型例と言えよう。
助手: 全体的な手続きの「流れ」を重視したプログラミングが何かいけないんでしょうか。
博士: いけないとまでは言っとらん。ただし,「オブジェクト指向プログラミング」的なセンスでこう書くこともできる。
<例2>
Sub Main() Dim t As Double = Timer Dim x As Integer = 100000 '** Dim PrimeNumber As New List(Of Integer) Dim counter As Integer = 0 Dim i As Integer = 2 Do Dim IsNotPrime As Boolean = False Dim j As Integer For Each j In PrimeNumber If (i \ j) * j = i Then IsNotPrime = True Exit For End If Next If Not IsNotPrime Then PrimeNumber.Add(i) counter += 1 If x = counter Then Debug.Print("{0}", Timer - t) MsgBox(x & "番目の素数は" & i & "です") Exit Sub End If End If i += 1 Loop End Sub
助手: なるほど。素数のリストを徐々に増やしていくやり方ですね。
博士: 「オブジェクト指向プログラミング」的なセンスを取り入れたことが伝わるかのう。どういうことかというと,素数のリストを重要な「オブジェクト」と捉え,これをList(Of Integer)クラスのPrimeNumberというインスタンス(=変数)で表現したのじゃ。ListクラスはMicrosoftによって提供されており,後から要素を追加していくことができる便利なクラスである。はじめは空っぽだったPrimeNumberインスタンスに発見した素数を追加していくことで素数のリストを育てていくイメージじゃ。
助手: PrimeNumber.Add(i)という部分で実際に素数を追加しているわけですね。それにしても,素数のリストをFor Each文で使うあたりがオシャレですねえ。
博士: (得意げに)そうじゃろそうじゃろ。とはいえ,Listクラスという強力なクラスを使うことさえ思いつけば,「オブジェクト指向プログラミング」などと大きく出る話ではない。
助手: そうすると,「オブジェクト指向プログラミング」にはまだ先があると?
博士: そうじゃ。<例2>をさらに「オブジェクト指向プログラミング」的に書き直すとこうもできる。
<例3>
Sub Main() Dim t As Double = Timer Dim x As Integer = 100000 '** Dim p As New PrimeNumber Dim i As Integer For i = 1 To x p.AddNextPrime() Next Debug.Print("{0}", Timer - t) MsgBox(x & "番目の素数は" & p(x - 1) & "です") End Sub Public Class PrimeNumber : Inherits List(Of Integer) Public Sub AddNextPrime() If Me.Count = 0 Then Me.Add(2) Exit Sub End If Dim i As Integer = Me.Last() + 1 Do Dim IsNotPrime As Boolean = False Dim j As Integer For Each j In Me If (i \ j) * j = i Then IsNotPrime = True Exit For End If Next If Not IsNotPrime Then Me.Add(i) Exit Sub End If i += 1 Loop End Sub End Class
助手: 基本的なロジックは変わっていないようですが,ClassとかInheritsとか見慣れないキーワードが出てきますねえ。
博士: Public Class PrimeNumber : Inherits List(Of Integer)の意味は,List(Of Integer)クラスを継承するPrimeNumberクラスを自ら定義するということじゃ。PrimeNumberクラスには,AddNextPrimeというメソッドが定義されているが,このメソッドのおかげで全体的な手続きの「流れ」が
Sub Main() Dim t As Double = Timer Dim x As Integer = 100000 '** Dim p As New PrimeNumber Dim i As Integer For i = 1 To x p.AddNextPrime() Next Debug.Print("{0}", Timer - t) MsgBox(x & "番目の素数は" & p(x - 1) & "です") End Sub
と,非常に直感的な形に書けている点が「オブジェクト指向プログラミング」の最大の恩恵じゃ。これならVBがわからなくても,全体的な手続きの「流れ」が一目瞭然ではないかな?
助手: 確かにおっしゃるとおりです。これならPrimeNumberクラスの定義をよく読まなくても,PrimeNumberクラスのpインスタンスに対して,p.AddNextPrime()で素数をポチポチ追加している雰囲気がよくわかります。かといって,PrimeNumberクラスの定義も決してわかりづらいわけではなく,全体としてプログラムが読みやすくなった気がします。
博士: そのとおりじゃ。素数リストという「オブジェクト」をPrimeNumberクラスとしてキャラ立ちさせ,エラトステネスのふるいに素数を追加するという固有の手続きをPrimeNumberクラスのAddNextPrimeメソッドとして切り出すことで,全体的な手続きの「流れ」の見通しがよくなったということじゃな。
助手: 恐れ入りました。。(その3に続く)
2012-08-22 20:05
nice!(0)
コメント(0)
トラックバック(0)
コメント 0