Mr.Tの場所

特攻野郎Aチームじゃないよー

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  253  : 記事  0  : コメント  3698  : トラックバック  52

ニュース

  • 性別:男
  • 猫1:まる
  • 猫2:もろ
  • 猫3:にゃん左部郎
  • タバコ:男は黙ってJPS
[わんくま同盟] C#, VB.NET 掲示板

書庫

日記カテゴリ

Mr.Tです、こんにちは。

Optionalで祭りが発生してから、実はすでに意識は別のところに...

というのは、例のとりこびとさんのエントリ

http://blogs.wankuma.com/torikobito/archive/2007/10/03/99289.aspx

この中の、とっちゃんのコメント。

実装が9割同じで...というのならそんなのは、private メソッドで下請けしてやればいいわけですからw

これに、反応。

#例によって、サンプルは、へたくそです。

実装がほとんど同じで、Privateで下請けってのは、こういうケースですよね?

Private Mr_T as 人 = new 人

Public overloads Sub 昼食を食べる(byval 味噌ラーメン as ラーメン)

 while (味噌ラーメン.量 >0)

      Mr_T.食べる(味噌ラーメン)

          味噌ラーメン.量 -= Mr_T.一度に食べる量

 loop

 Mr_T.感謝("ご馳走様でした")

end sub

 

Public overloads Sub 昼食を食べる(byval 味噌ラーメン as ラーメン,byval もやしキライ as boolean)

 if もやしきらい = True then

          Mr_T.取り除く(味噌ラーメン.もやし)

   味噌ラーメン.量 -= 味噌ラーメン.もやし.量

   end if

 while (味噌ラーメン.量 >0)

      Mr_T.食べる(味噌ラーメン)

          味噌ラーメン.量 -= Mr_T.一度に食べる量

 loop

 Mr_T.文句("もやしキライっていっただろぉ")

end sub

 

ここに、Private な「ラーメンを食べる」メソッドを追加。

Private Sub ラーメンを食べる(byval 食べる人 as 人,byval 味噌ラーメン as ラーメン)

 while (味噌ラーメン.量 >0)

      食べる人.食べる(味噌ラーメン)

          味噌ラーメン.量 -= 食べる人.一度に食べる量

 loop

end Sub

 

すると、

Public overloads Sub 昼食を食べる(byval 味噌ラーメン as ラーメン)

  ラーメンを食べる(Mr_T,味噌ラーメン)

 Mr_T.感謝("ご馳走様でした")

end sub

Public overloads Sub 昼食を食べる(byval 味噌ラーメン as ラーメン,byval もやしキライ as boolean)

 if もやしきらい = True then

          Mr_T.取り除く(味噌ラーメン.もやし)

   味噌ラーメン.量 -= 味噌ラーメン.もやし.量

   end if

  ラーメンを食べる(Mr_T,味噌ラーメン)

 Mr_T.文句("もやしキライっていっただろぉ")

end sub

 

とすっきり。

 

だけど、ちょっとまてよ、とよく考えることがあります。こういうメソッド内容だったら、どうすんだろう。

Private 娘 as 人 = Mr_T.子供

Public overloads Sub 昼食を食べる(byval 味噌ラーメン as ラーメン,byval もやしキライ as boolean)

 while (味噌ラーメン.量 >0)

    if もやしきらい = True then

             娘.取り除く(味噌ラーメン.もやし.一本)

       味噌ラーメン.量 -= 味噌ラーメン.もやし.一本

      end if

      娘.食べる(味噌ラーメン)

          味噌ラーメン.量 -= 娘.一度に食べる量

 loop

 娘.文句("もやし、いらん")

end sub

 

これって、ループの中にもやしの取り除きがある。でも、これってPrivateでやろうと思うと、切り出せないように

思う。でも、処理はほとんど一緒。

 

Private Sub ラーメンを食べる() に、もやしキライの引数を追加してもいいけど、ラーメンを食べるのは娘以外の人も食べるから、

必ずもやしキライとはならない。なので、もやしの取り除きを、ラーメン食べるメソッドには組み込みたくないです。

引数に、もやしキライであることを追加することは、そのケースが局所的すぎるように思います。

 

この場合、どう考えてきちんと組めばいいんだろう、と悩むんです...できるなら、Privateへの下請けだしたいのだけど...

投稿日時 : 2007年10月4日 0:42

コメント

# re: 引数をつけたいけど、つけない 2007/10/04 4:46 ひろえむ
んーっと、クラスとインスタンスが混合しているような気がするのは気のせいでしょうか?

たぶん本当ならばこのケースではOverloadsを利用しないで例えば
1.ラーメン食材の一覧をEnumなどで作成
2.嫌いリストのListをPrivateで持つ
3.Add嫌いリストメソッドを作成して、引数にラーメン食材Enumにして嫌いリストにAdd。
4.感謝メッセージのプロパティ、嫌い文句メッセージのプロパティ、1回で食べる量プロパティを持つ
5.食べるメソッドで
  1)嫌いリストより食材取り除き処理
  2)食べる処理
  3)嫌い食材リストのCount<>0のときに嫌いメッセージ表示、そうでないとき感謝メッセージ表示

というクラスを作成して、各Mr_Tさん娘さんインスタンスを作る感じになるんじゃないでしょうか?

# re: 引数をつけたいけど、つけない 2007/10/04 8:47 Mr.T
Mr.Tです、こんにちは。
例によって例のごとく、例が悪いような気がしてきました。

ひろえむさん、ありがとうございます。
>んーっと、クラスとインスタンスが混合しているような気がするのは気のせいでしょうか?
すみません、後から見直すと、混合してますね...
ラーメン食べるメソッド内で、Mr_Tと娘インスタンスで書くのではなく、適当な人インスタンスで一般化しないといけませんでしたorz

提示されている内容については、きちんと考えてみますね...

# re: 引数をつけたいけど、つけない 2007/10/04 9:48 ひろえむ
Public Class ラーメンを食べる人
Public Enum ラーメンの具

スープ
もやし
なると
チャーシュー
End Enum

Private _ラーメンの具一覧 As New ArrayList
Private _嫌いな具の一覧 As New ArrayList
Private _嫌いメッセージ As String = String.Empty
Private _感謝メッセージ As String = String.Empty

Public WriteOnly Property 嫌いメッセージ() As String
Set(ByVal Value As String)
嫌いメッセージ = Value
End Set
End Property

Public WriteOnly Property 感謝メッセージ() As String
Set(ByVal Value As String)
_感謝メッセージ = Value
End Set
End Property

Public Sub Add嫌いな具一覧(ByVal 嫌いな具 As ラーメンの具)
_嫌いな具の一覧.Add(嫌いな具)
End Sub

Private Sub ラーメンを作る()
_ラーメンの具一覧.Add(ラーメンの具.麺)
_ラーメンの具一覧.Add(ラーメンの具.スープ)
_ラーメンの具一覧.Add(ラーメンの具.なると)
_ラーメンの具一覧.Add(ラーメンの具.もやし)
_ラーメンの具一覧.Add(ラーメンの具.チャーシュー)
End Sub

Private Sub 嫌いな具をよける()
For Each 嫌いな具 As ラーメンの具 In _嫌いな具の一覧
_ラーメンの具一覧.Remove(嫌いな具)
Next
End Sub

Public Sub ラーメンを食べる(ByVal これから食べるラーメンの量 As Integer, ByVal 一回で食べられるラーメンの量 As Integer)
ラーメンを作る()
嫌いな具をよける()

Dim 現在食べているラーメンの量 As Integer = これから食べるラーメンの量
Do While 現在食べているラーメンの量 > 0
現在食べているラーメンの量 -= 一回で食べられるラーメンの量
Loop

If _嫌いな具の一覧.Count > 0 Then
Console.WriteLine(_嫌いメッセージ)
Else
Console.WriteLine(_感謝メッセージ)
End If
End Sub

End Class

こんなクラスかな?
これで、Mr_Tさんインスタンスと娘さんインスタンスを作ってプロパティやら嫌いな具を設定すればそれらしいことになるんじゃないでしょうか(^^;

手元にVS2003しかないので構文は2003です(^^;

# re: 引数をつけたいけど、つけない 2007/10/04 12:25 Mr.T
Mr.Tです、こんにちは。

サンプルありがとうございます>ひろえむさん
で、せっかくなので、これを元に、表題のことを再考してみるww

ここでは、ラーメンを食べるメソッドの実装は、嫌いな具は最初によけてから、食べる処理に入ります。

ところが、娘インスタンスの場合は、具をよける動作というのは、最初によける、という実装にはできないとします。(実際、できないですw>娘)
つまり、ループ中(食べている最中に)処理しないといけないわけです。

となると、ラーメンを食べるメソッドをオーバーロードしてしまいたくなる。>もしかして、これがまずい?

Public Sub ラーメンを食べる(ByVal これから食べるラーメンの量 As Integer, ByVal 一回で食べられるラーメンの量 As Integer,byval 嫌いな具コレクション as List(of ラーメンの具))

End Sub

でも、嫌いな具を引数にするなら、逆に好きな具も引数にしたくなる可能性がある。
そのたびに、オーバーロードして、引数増やして、個別処理ってのは面倒なんです。

なので、気持ちとしては、
ラーメンを食べる処理、
嫌いな具をよける処理
好きな具を先に食べる処理、
などのように、分化させてPrivate処理させたいのですね。
だけど、例のようにループ内でやらなくちゃいけない場合、Privateにくくりだせない...ように思います。

プログラムとしては、食べるメソッドのループ内に、嫌いな具であった場合のIF文が入り込むだけなので、
処理としては、ほとんど同じ...オーバーロードすると毎回ループをかかなくちゃいけない...
いやオーバーロードしてもいいけど、ループ処理やら、前処理、後処理は、
Public Sub ラーメンを食べる(ByVal これから食べるラーメンの量 As Integer, ByVal 一回で食べられるラーメンの量 As Integer)
にある、内容にまかせたいんですよね。

でも、処理の途中一部分だけを抜き取りして、オーバーライドって無理ですよね。

かといって、一つのメソッドで処理できるように、引数を増やして内部分岐しまうのは、食べる処理が肥大してしまいます。

どうにか、すっきりできんかなぁ、と思うんですが...



# re: 引数をつけたいけど、つけない 2007/10/04 13:12 とっちゃん
んー。もっと細かい単位で分割していけば解決できると思いますよ。

大枠のロジックとしては、それほど間違ってません。
おそらく、見誤っているのは、ラーメンを食べ始める前に完璧に除外ができていないということを見落としている点にあると思います。

さて、すこし細かい単位で考えてみましょう。
まずは、ラーメンを食べるときの全体の基本骨格。

ここで、処理するべきは、ラーメンを食べるということです。
とりあえず、嫌いなものが入っていないという理想的な状況を考えてみます(一番単純な処理になるので)。

この場合の処理としては、
while( ラーメン.量 > 0 ){
 人.一口食べる(ラーメン);
 if( 人.腹いっぱい ){
  break;
 }
}
になると思います。
#ここでは、腹がいっぱいになってしまう処理をあえて追加w
次に、除外処理も考えてみます。

while( 人.嫌いなものチェック( ラーメン ) ){
 人.嫌いなもの除外( ラーメン );
}
こんな感じですが、除外処理は失敗の可能性があります。
なので、エラー処理を入れる必要がありますので
while( 人.嫌いなものチェック( ラーメン ) ){
 if( 人.嫌いなもの除外( ラーメン ) == 失敗 ){
  break;
 }
}
という形にする必要があると思われます。
これを除外メソッドとして人に実装します。

ここでようやく、本筋になるわけですが...

Mr.T さんは除外処理を最初にやると言っていましたが、
そこに漏れが生じていると思われます。

食べてる最中に除外しきれなかった分を除外していませんか?
おいらは、あらかじめよける処理を行いますが、除外しきれないものが
あるので、結局食べてる最中にも除外処理が発動しますけど?

と言うところで、改めて考えてみてはどうでしょうか?

# re: 引数をつけたいけど、つけない 2007/10/04 13:37 とりこびと
う~ん。読み間違えてる可能性大ですが、

>ところが、娘インスタンスの場合は、具をよける動作というのは、最初によける、という実装にはできないとします。(実際、できないですw>娘)

>Public Sub ラーメンを食べる(ByVal これから食べるラーメンの量 As Integer, ByVal 一回で食べられるラーメンの量 As Integer,byval 嫌いな具コレクション as List(of ラーメンの具))

>End Sub

このオーバーロードって、意味あります?
・・・メンバ変数をあえて引数にとる?




# re: 引数をつけたいけど、つけない 2007/10/04 14:26 ひろえむ
んーっと、この例でいくとOverloadsするのは不自然ですね(^^;

できるなら「ラーメンを食べる子供クラス」を作って「ラーメンを食べる人」クラスを継承して処理が変わるところをOverrideしたり、追加したりってことが自然なんでしょうね(^^;

ラーメンを食べる人とラーメンを食べる子供では似ている部分はありますが、別の特性を持つということになるので、この場合別クラスにするのが自然でしょうね。

その上で、その特性に応じた食べ方をコーディングするのがいいと思います。

逆にOverloadsする例としてはラーメンの量や、1回で食べる量の基準値を設定するとかでしょうか。

そのときにはOptionalで設定して・・・という感じですっきりですw

# re: 引数をつけたいけど、つけない 2007/10/04 15:21 Mr.T
Mr.Tです、こんにちは。

コメントありがとうございます。設計とかをすっとばした、つたないサンプルで申し訳ないです。

とっちゃん:
>これを除外メソッドとして人に実装します。
おお、そうですね。人に実装しちゃえばいいのか。

while( ラーメン.量 > 0 ){
 人.除外処理(ラーメン)
 人.一口食べる(ラーメン);
 if( 人.腹いっぱい ){
  break;
 }
}

として、人クラスには、基本の除外処理をOverrideableとして実装しておく。

Public Class ラーメン食べる人
Public overridable Sub 除外処理(byval ミソラーメン as ラーメン)
  
End sub
人クラスを派生した、Mr_Tクラスと、娘クラスをつくる。

Mr_Tクラスでは、除外処理をオーバーライドするが、好き嫌いがないため、特に除外処理をしない個別実装をする

娘クラスでは、除外処理をオーバーライドして、娘独自の除外するような実装をする。

とすれば、大本のループ処理でラーメンを食べることになり、好き嫌いがあれば、その人の派生クラス内の独自実装で処理できる。

そっかー。そっかー。除外をラーメンにくっつけてたのが間違いだなぁ。そうすればすっきりです。

とりこびっちさん:
>このオーバーロードって、意味あります?
ぐはぁ....け、袈裟懸けに....

ひろえむさん:
>んーっと、この例でいくとOverloadsするのは不自然ですね(^^;
うごぉ...刀を返して、ぎゃ、逆袈裟に....

すみません、もー、Mr.TのTは適当のTです。
ラーメンを食べる処理の中に、嫌いなもんがあった場合を考えて、それを人に実装しないで、ラーメンに実装しちゃったのが敗因ですね。ラーメンが自発的によけてくれるわけじゃないですしね。


# re: 引数をつけたいけど、つけない 2007/10/04 16:09 とりこびと
いろんなひとの設計感が見えるおもしろい話題なので、どんどんやってほしいです。祭きぼー♪

>もー、Mr.TのTは適当のTです。

ジェネリックかと思ってましたがw

# re: 引数をつけたいけど、つけない 2007/10/04 16:12 とりこびと
あ、言い忘れましたけど、私も

>できるなら「ラーメンを食べる子供クラス」を作って「ラーメンを食べる人」クラスを継承して処理が変わるところをOverrideしたり、追加したりってことが自然なんでしょうね(^^;

と同じ感じです。

# ロレックスコピー 2023/05/27 20:13 coxAcquic
ブランド腕時計バッグ財布コピー エルメス(バッグ、時計) シャネル(バッグ、時計)ルイヴィトン(バッグ、時計) ブルガリ時計 グッチ(バッグ、小物) ロレック(時計)オメガ(時計) IWC(時計)FRANCK MULLER(時計)1.最も合理的な価格で商品を消費者に提供致します。2.弊社の商品品数大目で、商品は安めです!商品現物写真。3.数量制限無し、一個の注文も、OKです。4.1個も1万個も問わず、誠心誠意対応します。5.不良品の場合、弊社が無償で交換します。不明点、疑問点等があれば、ご遠慮なく言って下さい。}}}}}}
https://www.jpw128.com/product/detail-4380.html


Post Feedback

タイトル
名前
Url:
コメント