「オブジェクト指向プログラミング」について(その4) [プログラミング]
http://himakou.blog.so-net.ne.jp/2012-08-23 の続き
博士: これまでの三回の連載記事で,「オブジェクト指向プログラミング」の全体像について語ってきたが,どうであったか?
助手: ワタシは以下の二点がよくわかった気がします。
(1)「オブジェクト指向プログラミング」は,処理の「オブジェクト(=対象物)」を重視することによって,「オブジェクト」に固有の手続きに関するプログラミングを全体的な手続きの「流れ」から分離することを目指すものであり,プログラム全体の見通しをよくする効果がある。 (2)「オブジェクト指向プログラミング」は単なるプログラミング「手法」の一つにすぎないが,プログラム全体の見通しがよくなることで,プログラマの意図が他のプログラマに伝わりやすくなったり,バグ発生が抑えられたりする効果が期待できる。
博士: それでよい。今回は少し肩の力を抜いて,ゲームプログラマになったつもりで,プログラムを書いて遊んでみよう。助手: 何を言い出すんですか。ゲームプログラムなんてそんな簡単に書けるわけないじゃないですか。
博士: そう思うじゃろ。ところが,「オブジェクト指向プログラミング」のセンスを取り入れれば,多少の訓練で結構いい線までいくのじゃ。信じられないのも無理はないが,キミも30分後にはワシの言っている意味を理解しているであろう。
助手: (疑い深げに)そうだといいんですが。。。それでは何のゲームからいきましょうか。
博士: 肩慣らしに「ブロック崩しゲーム」のボールをプログラミングしてみよう。メインルーチンはこんな感じじゃ。
<例1>
助手: 雰囲気はわからないでもありませんが,少し解説してもらえませんか。
博士: ClsBallというクラスがあったと想像しつつ書いてみた。SetWallメソッドはXY座標(0,0)と(100,100)を結ぶ線分を対角線に持つ長方形が周囲の壁だとBallインスタンスに伝えるもので,SetPositionメソッドはXY座標(0,50)が自分の位置だとBallインスタンスに伝えるもので,SetVectorメソッドはX方向に1,Y方向に2というスピードで進んで行けとBallインスタンスに伝えるものじゃ。わかったか?
助手: わかりました。後はDo Loopの中でTimerがTimeSpan = 0.1秒経つ毎にMoveメソッドを呼び出して動かすわけですね。Moveメソッドを呼び出すとどうなるんですか?
博士: SetVectorメソッドでセットしたX方向に1,Y方向に2というスピードで一回進むつもりじゃ。
助手: でも,進んで行くといつか壁をはみだしちゃうんじゃないですか?
博士: だからSetWallメソッドであらかじめ周囲の壁をBallインスタンスに伝えておいたのじゃ。壁にぶつかったらBallインスタンスの方で勝手に方向を変えてくれるような設計を考えておる。いい機会だから教えておくが,「オブジェクト指向プログラミング」のポイントは,メインルーチンではオブジェクトたちへの情報提供と指示出しに徹することで,流れをできるだけわかりやすくすること。いわば信頼のおける部下への丸投げじゃな,ホッホッホッ。
助手: 何だか恐ろしいたとえですが,おっしゃりたい趣旨はわかりました。ボールが壁で反射するといった処理はメインルーチンで制御するのでなく,ボール自身に任せようというわけですね。
博士: そうじゃ。メインルーチンは具体的な「仕事」を極力しないように気をつけないといかん。よく,優秀なサラリーマンが管理職になったら部下の仕事に逐一手を出さずにいられないという悪い事例があるが,手を出さずに適切なアドバイスで部下を育てる方が結局は得策だというのに似ているな。
助手: はあ,ワタシは部下を持ったことがありませんのでまだピンときませんが,管理職がヒマなくらいの方が会社がうまくいくとということでしょうかね。
博士: すっかり脱線してしまった。ワシの意図がわかってもらえたようなので,後はキミ,ClsBallクラスの定義をやってくれんか。
助手: そうくると思っていました。こんな感じではいかがでしょうか。
<例2>
博士: 大変よく書けておる。壁をはみ出しそうになったら,Moveメソッドの中で適切にボールの位置を直しつつベクトルの向きを変えておけば,よい部下と言えるわけじゃ,ホッホッホッ。
助手: またもや恐れ入りました。
おしまい。
博士: これまでの三回の連載記事で,「オブジェクト指向プログラミング」の全体像について語ってきたが,どうであったか?
助手: ワタシは以下の二点がよくわかった気がします。
(1)「オブジェクト指向プログラミング」は,処理の「オブジェクト(=対象物)」を重視することによって,「オブジェクト」に固有の手続きに関するプログラミングを全体的な手続きの「流れ」から分離することを目指すものであり,プログラム全体の見通しをよくする効果がある。 (2)「オブジェクト指向プログラミング」は単なるプログラミング「手法」の一つにすぎないが,プログラム全体の見通しがよくなることで,プログラマの意図が他のプログラマに伝わりやすくなったり,バグ発生が抑えられたりする効果が期待できる。
博士: それでよい。今回は少し肩の力を抜いて,ゲームプログラマになったつもりで,プログラムを書いて遊んでみよう。助手: 何を言い出すんですか。ゲームプログラムなんてそんな簡単に書けるわけないじゃないですか。
博士: そう思うじゃろ。ところが,「オブジェクト指向プログラミング」のセンスを取り入れれば,多少の訓練で結構いい線までいくのじゃ。信じられないのも無理はないが,キミも30分後にはワシの言っている意味を理解しているであろう。
助手: (疑い深げに)そうだといいんですが。。。それでは何のゲームからいきましょうか。
博士: 肩慣らしに「ブロック崩しゲーム」のボールをプログラミングしてみよう。メインルーチンはこんな感じじゃ。
<例1>
Sub Main() Dim Ball As New ClsBall Ball.SetWall(0, 0, 100, 100) Ball.SetPosition(0, 50) Ball.SetVector(1, 2) '** Const TimeSpan As Double = 0.1 Dim t As Double = Timer Do If Timer - t >= TimeSpan Then t = Timer Ball.Move() End If Loop End Sub
助手: 雰囲気はわからないでもありませんが,少し解説してもらえませんか。
博士: ClsBallというクラスがあったと想像しつつ書いてみた。SetWallメソッドはXY座標(0,0)と(100,100)を結ぶ線分を対角線に持つ長方形が周囲の壁だとBallインスタンスに伝えるもので,SetPositionメソッドはXY座標(0,50)が自分の位置だとBallインスタンスに伝えるもので,SetVectorメソッドはX方向に1,Y方向に2というスピードで進んで行けとBallインスタンスに伝えるものじゃ。わかったか?
助手: わかりました。後はDo Loopの中でTimerがTimeSpan = 0.1秒経つ毎にMoveメソッドを呼び出して動かすわけですね。Moveメソッドを呼び出すとどうなるんですか?
博士: SetVectorメソッドでセットしたX方向に1,Y方向に2というスピードで一回進むつもりじゃ。
助手: でも,進んで行くといつか壁をはみだしちゃうんじゃないですか?
博士: だからSetWallメソッドであらかじめ周囲の壁をBallインスタンスに伝えておいたのじゃ。壁にぶつかったらBallインスタンスの方で勝手に方向を変えてくれるような設計を考えておる。いい機会だから教えておくが,「オブジェクト指向プログラミング」のポイントは,メインルーチンではオブジェクトたちへの情報提供と指示出しに徹することで,流れをできるだけわかりやすくすること。いわば信頼のおける部下への丸投げじゃな,ホッホッホッ。
助手: 何だか恐ろしいたとえですが,おっしゃりたい趣旨はわかりました。ボールが壁で反射するといった処理はメインルーチンで制御するのでなく,ボール自身に任せようというわけですね。
博士: そうじゃ。メインルーチンは具体的な「仕事」を極力しないように気をつけないといかん。よく,優秀なサラリーマンが管理職になったら部下の仕事に逐一手を出さずにいられないという悪い事例があるが,手を出さずに適切なアドバイスで部下を育てる方が結局は得策だというのに似ているな。
助手: はあ,ワタシは部下を持ったことがありませんのでまだピンときませんが,管理職がヒマなくらいの方が会社がうまくいくとということでしょうかね。
博士: すっかり脱線してしまった。ワシの意図がわかってもらえたようなので,後はキミ,ClsBallクラスの定義をやってくれんか。
助手: そうくると思っていました。こんな感じではいかがでしょうか。
<例2>
Public Class ClsBall Private wx0 As Integer, wy0 As Integer, wx1 As Integer, wy1 As Integer Public Sub SetWall(ByVal x0 As Integer, ByVal y0 As Integer, ByVal x1 As Integer, ByVal y1 As Integer) wx0 = x0 wy0 = y0 wx1 = x1 wy1 = y1 End Sub '** Private px As Integer, py As Integer Public Sub SetPosition(ByVal x0 As Integer, ByVal y0 As Integer) Me.Kill() px = x0 py = y0 Me.Draw() End Sub '** Private vx As Integer, vy As Integer Public Sub SetVector(ByVal x0 As Integer, ByVal y0 As Integer) vx = x0 vy = y0 End Sub '** Public Sub Move() Dim nx As Integer = px + vx If nx <= wx0 Then nx = wx0 * 2 - nx vx *= -1 ElseIf nx >= wx1 Then nx = wx1 * 2 - nx vx *= -1 End If Dim ny As Integer = py + vy If nx <= wx0 Then ny = wy0 * 2 - ny vy *= -1 ElseIf nx >= wx1 Then ny = wy1 * 2 - ny vy *= -1 End If Me.Kill() px = nx py = ny Me.Draw() End Sub '** Public Sub Kill() '**XY座標(px, py)にあるボールを消す End Sub '** Public Sub Draw() '**XY座標(px, py)にあるボールを描く End Sub End Class
博士: 大変よく書けておる。壁をはみ出しそうになったら,Moveメソッドの中で適切にボールの位置を直しつつベクトルの向きを変えておけば,よい部下と言えるわけじゃ,ホッホッホッ。
助手: またもや恐れ入りました。
おしまい。
2012-08-23 23:09
nice!(0)
コメント(0)
トラックバック(0)
コメント 0