SSブログ

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

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

博士: これまでの三回の連載記事で,「オブジェクト指向プログラミング」の全体像について語ってきたが,どうであったか?

助手: ワタシは以下の二点がよくわかった気がします。

(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メソッドの中で適切にボールの位置を直しつつベクトルの向きを変えておけば,よい部下と言えるわけじゃ,ホッホッホッ。

助手: またもや恐れ入りました。

おしまい。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

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

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

トラックバック 0

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