我が輩はオブジェクト指向について勉強中のものです
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
プロパティを設定してみました(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
start と go ではイメージがかぶり、
・どっちを使えば良いのか?
・実行順があるのか?
・処理の違いはあるのか?
が直感的に分からない。
irohenkan クラスが Form1 に依存しており、Form1 とセットで
無いと使えない。外部のタイマーや PictureBox を操作している
時点で使い勝手の悪いクラスになっている。クラスに分ける意味が無い。
オブジェクトとして独立するからには、それを作る目的があるのだろう
けど、色変換という目的においては、結局 Form1 がそもそも色変換画面
なのでしょう?
同じ目的のものを2つに分けるのでは、オブジェクト指向の概念が
理解できていないように思います。
現実世界で言うならあるラーメン店本店で修行した弟子が独立するのに、
いつまでたっても材料を本店から仕入れているようなもの。
効率が悪いし、使い勝手が悪い。ずっと弟子のままでいたほうが
まだマシって事です。
小手先のプログラムコードの問題ではなく、設計時の概念なのですから、
まずは何を考えて設計したのか説明してください。
> このような感じでいいものかどうかご意見聞かせてね。
変数 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 を継承したクラスに色変換の機能を持たせてしまうという手もあるかも。
改めて眺めてみると色変換クラスじゃなくて Timer クラスだよね。。。これ。
オブジェクト指向で作られた Timer クラスの機能を改悪した感じ。
フォームもタイマーもオブジェクト指向に基づいたオブジェクトです。
> もっともこのようなプログラムはオブジェクト指向でつくるのは時間の
> 無駄だと思いますが
むしろ壊してます。自分で作るより先に既存のオブジェクトのつくりを
理解して、使いこなせるような勉強をしたほうが良いのでは?
目的も見えていない、利便性も理解していないでは program(=計画)なんて
できるはずもなし。
> あるいは、フォーム側で Timer1_Tick イベントを制御しなくても良いよう、
> タイミング制御も色変換クラスに一任させてしまうという実装パターンもあるでしょう。
> henkan.Target = PictureBox1
そのオブジェクトは「あり」だけど、PictureBox1 別のオブジェクトであり、
その管理は Form1 がすべきって事を前面に出せば New して Start したら一定の間隔で
色変更イベントを起こして、そのイベントは引数として変更後の色データを持っている
とか。もちろん Form1 も Timer1 も PictureBox1 も参照しません。
あくまで一定時間毎に変異する色データを出力し続けるクラスです。
まさに、Timer クラスを継承した拡張クラスですね。
ネタ的に
[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
VBやってきましたが、オブジェクト指向に関するいい本がなかったので
矢沢先生の「標準C#入門」を読みながら、見よう見まねで作ってみましたが
やはり、およびでなかったようですね〜(本音はガクッツ、建前は建設的な姿勢をみせようとするあたし=あたしは二重人格のアナグロちゃん)
おしえてもらったソースを参考にしながら、しっかり学んでいきたいと
思っております。プログラミングに溺れるくらいに夢中になりたいボクちゃんでした。ありがとう。(ありがと〜ありがとう♪ こんな歌ありましたね)
良い本との出会いは重要ですが、所詮きっかけに過ぎず、単純に経験不足でしょう。
ここでいう経験不足というのは努力不足です。演習不足。
数学とか論理的な思考とか。。。数学脳に関しては解いた演習問題の数が実力の
ものさしだと思います。
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放置決定です。
「君は初心者にすらなっていないのに初心者だと思っているんだ?」
「ずーっと同じこと言っていれば良いんじゃない?」
認識が甘いだけですよ。この程度の話で落ち込むなら、プログラムなんか
しない方が幸せな人生が待ってると思います。道なんていくらでもあるんだから
幸せになることをお勧めします。
真剣に取り組んでる方が参考にして欲しい数も書いておきます。
> ネタ的に
で作ったウル○ラマンカラータイマーClassですが、
定時後20分で作ってます。このクラスの関数の数は5ですよね?
調子がいいときは1時間で10個とかで計算してもいいと思います。
もちろん単体テスト完のレベルで構いません。
結合テストはパターンを考える必要があるので次のレベルと考え、
計算にいれない前提です。
一般人でも1年かければ数万とか普通に作れますので安心してください。
むしろ重要なのは、だらだらと長い関数を作るとクリアできないと
いう点です。
あー、あと、高校生くらいの基準で書いてます。
小学生でもプログラムしてる人は居ると思いますが、
ウル○ラマンを知らない人にカラータイマークラスは無理ですw
人生経験というものは大事で、1年長く生きていれば、その分の
経験からの発想力が備わります。
まさに「その発想は無かった」って事です。気にしないで下さい。
関数の数の目標も小学生ではクリアするのは難しいと思います。
中学・高校・大学 or 就職、私的なことも含めてたくさんの経験を
得ることでできるようになると思います。
ウル○ラマンとの出会いもあるかもしれませんww
その時点でクリアできるようになれば十分です。
目標はあくまで目標。クリアできれば素晴らしいですが、できなく
てもマイナスにはなりません。過程を大事にしてください。
課題を作ってそこを目指すことで、決して0のままでは居られない
ようにすることが大事なのです。
特攻隊長さんの(なぜハンドルネームはこうなの?)
たいへん説得力のあるお言葉、おもわずうなずきました。
とにかく「コードを書け、書け、書くんだジョー」といったところですか。
毎日、少なくとも一つは(小さなプログラムでも)をちまちまと書いていこうと思ってます。要は、いい意味での中毒になればいいのですよね。
プログラミングをすれば脳内麻薬が分泌されるようにしていけばいい
ということかな、
とにかく楽しく、楽しくやっていこうと思います。
それでダメでも、過程が大切という言葉にはおおいに励まされました
ありがと〜
アナログさんへ
>いいものかどうかご意見聞かせてね。
>ありがと〜
ご意見聞かせてください。
ありがとうございました。
のように書けませんか?
他にも指摘できるところはたくさんあります。
回答されているかたも基本的には敬語を使っています。
教えていただくという立場としては非常識ですよ。
> のように書けませんか?
そういうキャラクターの演出なので書けないと思いますよ。
しょっぱなから
>我が輩は
ですもん。
基本的にボクもそうなんですが、わざとそういった言葉を使ってます。
まぁ、ボクはその効果まで考慮に入れていますし、効果を把握した上で
相手を選んでから使ってるから凶悪なんですがw
自分自身がそうだから、ボクはそこは特に気になりません。
逆に注意してどうこうなるもんでもないと思ってます。
もともと質問のプログラムコードを見るとVB中学校さんで
質問してた方の流れを汲んでます。
この方、回答が付いてる質問文を平気で削除できる人ですし、
違うサイトをうろちょろして腰が落ち着かない上にハンドルも
変えました。
そんなことしたら本人の頭の中ぐちゃぐちゃだと思います。
自分の行動は自分に跳ね返ります。
生暖かく見守ればいいと思います。
>生暖かく見守ればいいと思います。
ネット社会はそれが一番ですね。
因果応報は天の摂理です。
これで遊んで。
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
> これで遊んで。
ダメピヨ♪
>基本的にボクもそうなんですが、わざとそういった言葉を使ってます。
>まぁ、ボクはその効果まで考慮に入れていますし、効果を把握した上で
>相手を選んでから使ってるから凶悪なんですがw
凶悪という言葉を使うことは悲しいですね。
あなたは、自分を卑下しているのですか。
もっと自分を肯定してあげてください。
素晴らしい貴方の魂が悲しんでいますよ。
なぜわざとC調ぶるのでしょうか?
もっともネット上ではそうした演出は許されていいものかもしれませんね
あなたはあなたでいい。それが結論です。失礼
invalidateのクラスはいらなかったなぁ。
中2とか中3で、できますよ。冗談抜きで。
visualBasic2008入門の本は?ソフトバンクのやつ。
2400円+税です。
>invalidateのクラスはいらなかったなぁ。
Invalidateはクラスじゃなくてメソッドだよ
クラス=メソッドじゃないの?
違いを500文字以内で書いてみて^^
なにぶん初心者なんで。
あとさ
フロチャートとアルゴリズムの違いも教えてよ。
質問があるなら自分でスレたてなさい。
クラス -> プロパティ、メソッド、イベントで構成された処理の纏まり。
メソッド -> ひとつの処理(プロシージャ)
※ 1クラス内に1メソッドのみを実装しても違反にはならない(そもそも違反という考え方はないけどね。
周りの人に奇異の目で見られるだけ)が、あまりやる人はいないでしょう。
(例としてファイル操作を目的としたクラス作成時にオープンのみのクラスとかはまず作らないでし
ょう。また、クローズのみのクラス・・・以下同)
アルゴリズム -> 考え方、概念
フロチャート -> 考え方、概念を特定の図形を用いて表す方式
もっと良い説明がほしいならネット上で検索してください。私より説明上手な人は多いでしょうから。
ふむ。
まぁ、プログラムが動けば良い。
ツイート | ![]() |