オブジェクト指向について


アナログ  2009-08-20 20:19:10  No: 146226

我が輩はオブジェクト指向について勉強中のものです
PictureBoxの色を周期的に変化するプログラムを作って
みました。(もっともこのようなプログラムはオブジェクト指向
でつくるのは時間の無駄だと思いますが)
このような感じでいいものかどうかご意見聞かせてね。
え〜なにこれ  (@_@)とあきれないでくださいねなにしろとうしろうなものですから。

Public Class Form1
    Dim henkan As irohenkan = New irohenkan '色変換クラスのインスタンス生成

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        henkan.start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        henkan.go()

    End Sub
End Class
Class irohenkan '色変換クラス
    Private dx As Integer = 40

    Sub start()
        Form1.Timer1.Start()
    End Sub

    Sub go()
        dx = 100 - dx
        If dx < 60 Then
            Form1.PictureBox1.BackColor = Color.GreenYellow
            Form1.Timer1.Interval = 2000
        Else

            Form1.PictureBox1.BackColor = Color.Gold

        End If

    End Sub
End Class


アナログ  2009-08-20 22:18:25  No: 146227

プロパティを設定してみました(VB2008)
Public Class Form1
    Dim henkan As irohenkan = New irohenkan '色変換クラスのインスタンス生成

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        henkan.start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        henkan.go()

    End Sub
End Class
Class irohenkan '色変換クラス
    Private dx As Integer
    Sub go()
        dx = 1 - dx
        If dx > 0 Then
            Form1.PictureBox1.BackColor = Color.GreenYellow
            Form1.Timer1.Interval = 2000
        Else

            Form1.PictureBox1.BackColor = Color.Gold

        End If

    End Sub

    Public Property taiki() As Integer
        Get
            Return dx
        End Get
        Set(ByVal value As Integer)
            If value = 0 Then dx = value
        End Set
    End Property

    Sub start()
        Form1.Timer1.Start()
    End Sub
End Class


特攻隊長まるるう  2009-08-20 22:42:33  No: 146228

start と go ではイメージがかぶり、
・どっちを使えば良いのか?
・実行順があるのか?
・処理の違いはあるのか?
が直感的に分からない。

irohenkan クラスが Form1 に依存しており、Form1 とセットで
無いと使えない。外部のタイマーや PictureBox を操作している
時点で使い勝手の悪いクラスになっている。クラスに分ける意味が無い。

オブジェクトとして独立するからには、それを作る目的があるのだろう
けど、色変換という目的においては、結局 Form1 がそもそも色変換画面
なのでしょう?
同じ目的のものを2つに分けるのでは、オブジェクト指向の概念が
理解できていないように思います。

現実世界で言うならあるラーメン店本店で修行した弟子が独立するのに、
いつまでたっても材料を本店から仕入れているようなもの。
効率が悪いし、使い勝手が悪い。ずっと弟子のままでいたほうが
まだマシって事です。

小手先のプログラムコードの問題ではなく、設計時の概念なのですから、
まずは何を考えて設計したのか説明してください。


魔界の仮面弁士  2009-08-20 22:46:53  No: 146229

> このような感じでいいものかどうかご意見聞かせてね。

変数 dx の扱いが適切ではないなど、幾つかの問題点がありますが、
最大の問題は、それぞれのクラス(Form1/irohenkan) の役割が
きちんと線引きされていないことです。

まず、Form1 から irohenkan を呼び出していて、さらに
irohenkan からも Form1 を呼び出していますよね。

この実装では、クラス間の依存性が高くなりすぎてしまっており、
充分な役割分担ができていません。

現在は、呼び出し元となる Form1 と呼び出される側である irohenkan のそれぞれが
  ・Form1 側: Timer1_Tick で、go メソッドを呼ぶ。
  ・irohenkan 側: go で、Timer1.Interval を変更する。
を処理することが前提となっていますよね。

そのため、このクラスを他のフォームで再利用することができませんし、
対象コントロールやタイマーを別のものに差し替える場合には、
Form1 と irohenkan の両方を直さねばなりません。

結果として、クラスを分ける意味が無いどころか、使い勝手が悪化してしまっています。

たとえばこのクラス設計を見直して、

Public Class Form1
    Private henkan As New IroHenkan()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        henkan.Colors.Add(Color.GreenYellow)
        henkan.Colors.Add(Color.Gold)
        henkan.Colors.Add(Color.Blue)
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        PictureBox1.BackColor = henkan.GetNextColor()  'Colors で指定した色が順番に返される。
    End Sub
End Class

のようにすれば、IroHenkan クラスは色の管理のみに注力することができます。
(特定のコントロールに依存しなくなったため、IroHenkan クラスの再利用性が高まる)

あるいは、フォーム側で Timer1_Tick イベントを制御しなくても良いよう、
タイミング制御も色変換クラスに一任させてしまうという実装パターンもあるでしょう。

Public Class Form1
    Dim henkan As New IroHenkan()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        henkan.Target = PictureBox1
        henkan.Internval = 2000
        henkan.Colors.Add(Color.GreenYellow)
        henkan.Colors.Add(Color.Gold)
        henkan.Colors.Add(Color.Cornsilk)
        henkan.Start()   'これ以降、2秒間隔で PictureBox の背景色が切り替わる
    End Sub
End Sub

あるいは、PictureBox を継承したクラスに色変換の機能を持たせてしまうという手もあるかも。


特攻隊長まるるう  2009-08-20 23:14:40  No: 146230

改めて眺めてみると色変換クラスじゃなくて Timer クラスだよね。。。これ。
オブジェクト指向で作られた Timer クラスの機能を改悪した感じ。

フォームもタイマーもオブジェクト指向に基づいたオブジェクトです。
> もっともこのようなプログラムはオブジェクト指向でつくるのは時間の
> 無駄だと思いますが
むしろ壊してます。自分で作るより先に既存のオブジェクトのつくりを
理解して、使いこなせるような勉強をしたほうが良いのでは?
目的も見えていない、利便性も理解していないでは program(=計画)なんて
できるはずもなし。

> あるいは、フォーム側で Timer1_Tick イベントを制御しなくても良いよう、
> タイミング制御も色変換クラスに一任させてしまうという実装パターンもあるでしょう。
>        henkan.Target = PictureBox1
そのオブジェクトは「あり」だけど、PictureBox1 別のオブジェクトであり、
その管理は Form1 がすべきって事を前面に出せば New して Start したら一定の間隔で
色変更イベントを起こして、そのイベントは引数として変更後の色データを持っている
とか。もちろん Form1 も Timer1 も PictureBox1 も参照しません。
あくまで一定時間毎に変異する色データを出力し続けるクラスです。
まさに、Timer クラスを継承した拡張クラスですね。


特攻隊長まるるう  2009-08-21 02:51:57  No: 146231

ネタ的に
[VB2008]
    Public Class ColorTimer
        Private _ColorsNow As Colors
        Private WithEvents _myTimer As Timer
        Private _EmergencyCount As Integer
        Public Event ColorChange(ByVal ColorX As System.Drawing.Color)

        Public Enum Colors
            SetUp
            Nomal
            Emergency1
            Emergency2
            TimeOut
        End Enum

        Sub New()
            _myTimer = New Timer
            Call Reset()
        End Sub

        Public Sub Reset()
            _ColorsNow = Colors.SetUp
            _EmergencyCount = 0
            _myTimer.Interval = 3
            _myTimer.Start()
        End Sub

        Public Function GetColors(ByVal Index As Colors) As System.Drawing.Color
            Select Case Index
                Case Colors.Nomal
                    Return Color.Lime
                Case Colors.Emergency1
                    Return Color.Red
                Case Colors.Emergency2
                    Return Color.White
                Case Colors.TimeOut
                    Return Color.Gray
                Case Else
                    Return Color.Black
            End Select
        End Function

        Public ReadOnly Property ColorsNow() As System.Drawing.Color
            Get
                Debug.WriteLine(Me._ColorsNow)
                Return GetColors(Me._ColorsNow)
            End Get
        End Property

        Private Sub _myTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles _myTimer.Tick
            With DirectCast(sender, Timer)
                .Stop()
                Select Case Me._ColorsNow
                    Case Colors.SetUp
                        Me._ColorsNow = Colors.Nomal
                        RaiseEvent ColorChange(ColorsNow)
                        _myTimer.Interval = 3 * 60 * 1000
                        '_myTimer.Interval = 3 * 1000
                        .Start()

                    Case Colors.Nomal
                        Me._ColorsNow = Colors.Emergency1
                        RaiseEvent ColorChange(ColorsNow)
                        .Interval = 1000
                        .Start()

                    Case Colors.Emergency1, Colors.Emergency2
                        Me._EmergencyCount += 1
                        If Me._EmergencyCount > 30 Then
                            Me._ColorsNow = Colors.TimeOut
                        ElseIf Me._ColorsNow = Colors.Emergency1 Then
                            Me._ColorsNow = Colors.Emergency2
                        Else
                            Me._ColorsNow = Colors.Emergency1
                        End If
                        RaiseEvent ColorChange(ColorsNow)
                        .Start()

                    Case Else
                        '終了
                End Select

            End With
        End Sub

    End Class


アナログ  2009-08-21 04:17:18  No: 146232

VBやってきましたが、オブジェクト指向に関するいい本がなかったので
矢沢先生の「標準C#入門」を読みながら、見よう見まねで作ってみましたが
やはり、およびでなかったようですね〜(本音はガクッツ、建前は建設的な姿勢をみせようとするあたし=あたしは二重人格のアナグロちゃん)

おしえてもらったソースを参考にしながら、しっかり学んでいきたいと
思っております。プログラミングに溺れるくらいに夢中になりたいボクちゃんでした。ありがとう。(ありがと〜ありがとう♪  こんな歌ありましたね)


特攻隊長まるるう  2009-08-21 19:14:11  No: 146233

良い本との出会いは重要ですが、所詮きっかけに過ぎず、単純に経験不足でしょう。
ここでいう経験不足というのは努力不足です。演習不足。

数学とか論理的な思考とか。。。数学脳に関しては解いた演習問題の数が実力の
ものさしだと思います。
VBで言えば自分で作成した関数の数(サンプルコードのコピペは含みません。
単体テスト完までを基本とします)次第だと思います。
少なく見積もっても1時間で1個、1日8個として月に160個、1年に2千弱、
まぁ実際には仕様書作成とか他のことしてたら半分くらいなのかなぁ?。。。

ま、とにかく千個単位の話だろうということです。

数千個の関数を自分の力で作ってやっと駆け出し、つまり初心者。プロとして
職業にするなら数万レベルでしょうね。
そのくらい書いていれば、他のコントロールに依存してたら使い勝手が悪い
というのは「実感」してるはずなんですよね。既存の VB のクラスを参考に
するように書きましたが、画面に TextBox1 を貼り付けて使おうとしたら
『Form1 と Timer1 と Picture1 が必要です』なんてエラーメッセージが
出たら、そんなの使い物にならんでしょう?どう考えても。

質問しなければ分からない話ではありません。自分で気づくべき問題ですし、
それに気づかないなら、そのこと自体が問題なのです。
勿論、その「気づき」は数千個の演習問題を自分の力で解くことによって
養われます。やってないのにできないのであればそれは自然なことであり、
やるまでできるようになることはありません。
# やってできない場合は、やり方が悪い場合があるのでそこを検討しましょう。

どっちかっていうとプログラムの本より↓こういう本のほうが良いのでは?
「なぜ数学が「得意な人」と「苦手な人」がいるのか」
http://www.amazon.co.jp/%E3%81%AA%E3%81%9C%E6%95%B0%E5%AD%A6%E3%81%8C%E3%80%8C%E5%BE%97%E6%84%8F%E3%81%AA%E4%BA%BA%E3%80%8D%E3%81%A8%E3%80%8C%E8%8B%A6%E6%89%8B%E3%81%AA%E4%BA%BA%E3%80%8D%E3%81%8C%E3%81%84%E3%82%8B%E3%81%AE%E3%81%8B-%E3%83%96%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3-%E3%83%90%E3%82%BF%E3%83%BC%E3%83%AF%E3%83%BC%E3%82%B9/dp/4072283355
「数学脳をつくる」
http://www.yononaka.net/toshokan/sugaku.html

別にこの質問者に限った話ではありません。質問掲示板利用者の80%以上が
そうだと思います。そこで「初心者だから」とか言う人が一番引きますね。
勿論なにもつっこみませんがw放置決定です。
「君は初心者にすらなっていないのに初心者だと思っているんだ?」
「ずーっと同じこと言っていれば良いんじゃない?」
認識が甘いだけですよ。この程度の話で落ち込むなら、プログラムなんか
しない方が幸せな人生が待ってると思います。道なんていくらでもあるんだから
幸せになることをお勧めします。


特攻隊長まるるう  2009-08-21 19:30:41  No: 146234

真剣に取り組んでる方が参考にして欲しい数も書いておきます。
> ネタ的に
で作ったウル○ラマンカラータイマーClassですが、
定時後20分で作ってます。このクラスの関数の数は5ですよね?
調子がいいときは1時間で10個とかで計算してもいいと思います。
もちろん単体テスト完のレベルで構いません。
結合テストはパターンを考える必要があるので次のレベルと考え、
計算にいれない前提です。

一般人でも1年かければ数万とか普通に作れますので安心してください。
むしろ重要なのは、だらだらと長い関数を作るとクリアできないと
いう点です。


特攻隊長まるるう  2009-08-21 21:21:43  No: 146235

あー、あと、高校生くらいの基準で書いてます。

小学生でもプログラムしてる人は居ると思いますが、
ウル○ラマンを知らない人にカラータイマークラスは無理ですw
人生経験というものは大事で、1年長く生きていれば、その分の
経験からの発想力が備わります。
まさに「その発想は無かった」って事です。気にしないで下さい。

関数の数の目標も小学生ではクリアするのは難しいと思います。
中学・高校・大学 or 就職、私的なことも含めてたくさんの経験を
得ることでできるようになると思います。
ウル○ラマンとの出会いもあるかもしれませんww
その時点でクリアできるようになれば十分です。

目標はあくまで目標。クリアできれば素晴らしいですが、できなく
てもマイナスにはなりません。過程を大事にしてください。
課題を作ってそこを目指すことで、決して0のままでは居られない
ようにすることが大事なのです。


アナログ  2009-08-23 01:00:30  No: 146236

特攻隊長さんの(なぜハンドルネームはこうなの?)
たいへん説得力のあるお言葉、おもわずうなずきました。
とにかく「コードを書け、書け、書くんだジョー」といったところですか。

毎日、少なくとも一つは(小さなプログラムでも)をちまちまと書いていこうと思ってます。要は、いい意味での中毒になればいいのですよね。
プログラミングをすれば脳内麻薬が分泌されるようにしていけばいい
ということかな、
とにかく楽しく、楽しくやっていこうと思います。
それでダメでも、過程が大切という言葉にはおおいに励まされました
ありがと〜


59967041  2009-08-23 05:55:32  No: 146237

アナログさんへ

>いいものかどうかご意見聞かせてね。
>ありがと〜

ご意見聞かせてください。
ありがとうございました。

のように書けませんか?
他にも指摘できるところはたくさんあります。
回答されているかたも基本的には敬語を使っています。
教えていただくという立場としては非常識ですよ。


特攻隊長まるるう  2009-08-24 18:53:37  No: 146238

> のように書けませんか?
そういうキャラクターの演出なので書けないと思いますよ。
しょっぱなから
>我が輩は
ですもん。

基本的にボクもそうなんですが、わざとそういった言葉を使ってます。
まぁ、ボクはその効果まで考慮に入れていますし、効果を把握した上で
相手を選んでから使ってるから凶悪なんですがw
自分自身がそうだから、ボクはそこは特に気になりません。
逆に注意してどうこうなるもんでもないと思ってます。

もともと質問のプログラムコードを見るとVB中学校さんで
質問してた方の流れを汲んでます。
この方、回答が付いてる質問文を平気で削除できる人ですし、
違うサイトをうろちょろして腰が落ち着かない上にハンドルも
変えました。
そんなことしたら本人の頭の中ぐちゃぐちゃだと思います。
自分の行動は自分に跳ね返ります。
生暖かく見守ればいいと思います。


通行人  2009-08-24 22:03:26  No: 146239

>生暖かく見守ればいいと思います。
ネット社会はそれが一番ですね。
因果応報は天の摂理です。


れお  2009-08-25 01:53:10  No: 146240

これで遊んで。
Option Strict On
'VisualBasic2008
Public Class Form1
    Private red As Integer
    Private green As Integer
    Private blue As Integer
    Private myRandom As System.Random
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Timer1.Enabled = True
        Timer1.Interval = 500
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        myRandom = New System.Random()
        red = myRandom.Next(255)
        green = myRandom.Next(255)
        blue = myRandom.Next(255)
        PictureBox1.BackColor = Color.FromArgb(255, red, green, blue)
        PictureBox1.Invalidate()
    End Sub
End Class


れおは詐欺師  2009-08-26 20:52:51  No: 146241

> これで遊んで。
ダメピヨ♪


無記  2009-08-27 05:35:56  No: 146242

>基本的にボクもそうなんですが、わざとそういった言葉を使ってます。
>まぁ、ボクはその効果まで考慮に入れていますし、効果を把握した上で
>相手を選んでから使ってるから凶悪なんですがw
凶悪という言葉を使うことは悲しいですね。
あなたは、自分を卑下しているのですか。
もっと自分を肯定してあげてください。
素晴らしい貴方の魂が悲しんでいますよ。
なぜわざとC調ぶるのでしょうか?
もっともネット上ではそうした演出は許されていいものかもしれませんね
あなたはあなたでいい。それが結論です。失礼


れお  2009-08-27 09:29:08  No: 146243

invalidateのクラスはいらなかったなぁ。
中2とか中3で、できますよ。冗談抜きで。

visualBasic2008入門の本は?ソフトバンクのやつ。
2400円+税です。


47192382  2009-08-27 10:47:45  No: 146244

>invalidateのクラスはいらなかったなぁ。
Invalidateはクラスじゃなくてメソッドだよ


れお  2009-08-28 11:51:06  No: 146245

クラス=メソッドじゃないの?
違いを500文字以内で書いてみて^^
なにぶん初心者なんで。
あとさ
フロチャートとアルゴリズムの違いも教えてよ。


GOD  2009-08-28 18:43:08  No: 146246

質問があるなら自分でスレたてなさい。

クラス   -> プロパティ、メソッド、イベントで構成された処理の纏まり。
メソッド -> ひとつの処理(プロシージャ)
※ 1クラス内に1メソッドのみを実装しても違反にはならない(そもそも違反という考え方はないけどね。
周りの人に奇異の目で見られるだけ)が、あまりやる人はいないでしょう。
  (例としてファイル操作を目的としたクラス作成時にオープンのみのクラスとかはまず作らないでし
  ょう。また、クローズのみのクラス・・・以下同)

アルゴリズム -> 考え方、概念
フロチャート -> 考え方、概念を特定の図形を用いて表す方式

もっと良い説明がほしいならネット上で検索してください。私より説明上手な人は多いでしょうから。


れお  2009-08-29 01:47:32  No: 146247

ふむ。
まぁ、プログラムが動けば良い。


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加