R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

部品化する場合としない場合(その2)

http://blogs.wankuma.com/rti/archive/2007/06/12/80453.aspx
部品化する場合としない場合

の続きです。

そもそも、じゃんぬねっとさんのコメントに対するコメントとして書いたのですが、折角なのでネタとして僕の考えをまとめておきます。

さて、このタイトルも前回のタイトルもそうですが、テーマとしては次のようなものです。

あるデータがあります。
そのデータに特化したコントロールを作る場合と作らない場合があります。

これは、

ケースバイケース

に他なりません。

これが、最初から言っている僕の意見です。

誤解のないように言っておきますが、コントロール内部でデータ本体を持つことは反対です。
これは一度もやったことがありません。
基本的には、データを格納するクラス(型付きデータセットとか、List<> とか)を作って、そこに放り込んでバインドします。
この方法は常に変わりません。

データソースはデータベースであったり、そのクラス自身に持たせたりします。

さて本題です。
では、素敵だし爽やかRさんは、馬鹿のひとつ覚えのようにケースバイエースと言っています。

では、どういう場面においてデータに特化したコントロールを作るのでしょうか?

まずは、前回ちょっと触れた都道府県データに関する例を考えてみます。

都道府県・市区町村を選択する局面において、まずは DataTable オブジェクトに都道府県データを突っ込みます。
これだけなら別段、都道府県に特化したコンボボックスを作ろうとは思いません。

では、都道府県を選択するコンボボックスが大量に必要になった場合はどうでしょうか?
方法は3つ考えられます。

どの方法を使いますか?

 

  1. 標準コンボを毎回バインドする処理、あるいはプロパティを設定する
  2. データソースウィンドウからテーブルのフィールドのコントロールをコンボボックスに指定してフォームに貼り付ける
  3. コンボボックスを拡張してバインドの処理を含めてしまう
  4. その他

僕は、3つめを選択します。

次に、市区町村を選択する必要も出てきたとします。
都道府県を変更することで、市区町村の選択肢は、その都道府県に準じたものになります。
このやり方は、市区町村TableAdapter に FillBy都道府県(string prefectureValue) なりを追加して実行したデータを市区町村コンボにバインドします。

しかし、このような処理が複数のフォームで必要になった時、これらはユーザーコントロールにしても良いと思います。

あるいは、商品マスターの商品コードを入力するケースです。
商品マスターを入力するテキストボックスをシステム全体から見た時に、大量に使うことになります。
これは、以下の要件を備えたものになります。

・テキストボックスは、ANKの16バイトの入力制限付き、更に商品マスターの存在チェックまでしなくてはならない。
・入力された文字列は、有効なら黒色、無効なら赤色表示。
・無効状態なら、他の入力ボックスのフォーカスに移動できない。
(つい先日、似たようなものを作ったばかりです)

どの方法を使いますか?

  1. 毎回プロパティに設定、イベントも記述。
  2. 入力規則の下請けメソッドを作って共通で呼びまわす。
  3. 品番入力ボックスをテキストボックスから拡張。
  4. その他。

僕はやっぱり品番入力ボックスを作りますね。
ちなみに、品番入力ボックスの右に「参照」ボタンを付けて、品番検索ダイアログボックスが開くように機能追加した時に、とっても楽でした。

上記のケースは、何れも、あるデータに特化した専用のコントロールになります。
名前も、都道府県選択ボックス・市区町村選択ボックス・品番入力ボックスというコントロールです。
そして、これらのコントロールは、生産性も品質も向上させるものになると思います。

こういうケースはあって良いと思うので「データごとにコントロールを作るべきではない」という意見に、ケースバイケースでしょうと言っただけの話です。

上記のような、コントロールの存在を許したら、存在するデータの数だけコントロールを作らなくてはいけない訳ではありませんよね。

基本的に、既存のコントロールにバインドしてあげる。
データに特化したコントロールは必要に応じて作る。

ケースバイケースです。

投稿日時 : 2007年6月15日 12:02

Feedback

# re: 部品化する場合としない場合(その2) 2007/06/15 14:17 trapemiya

部品化する場合、汎用的なものと、あるプロジェクトに特化しているものと2種類あるんじゃないでしょうか?

標準コントロールとして用意されてないが、標準コントロールとしてもいいような汎用的なコントロールは部品化します。例えばフリガナを自動で生成してくれるテキストボックスなどです。

汎用的ではなくプロジェクトに特化している場合の部品化は、保守を含めトータルで工数削減になるかどうかだと思います。ビジネスロジックを入れることで逃げれるのであれば、部品化するまでもないと思います。

TableAdapterはある種の部品化だと思うのですが、汎用的ではなく、そのプロジェクトに特化し、工数減を目的としていると思います。上記原則に立てば、TableAdapterを採用する場合は、この結果としてどれほど工数が削減できるのだろうか?また、保守しやすいんだろうか?のバランスで悩むことになります。

結論から言えば、ケースバイケースですね。

# re: 部品化する場合としない場合(その2) 2007/06/15 15:15 じゃんぬねっと

ちょーっと範囲を広げすぎかなぁと思います。記事としては良いと思いますが、もしこれが私に対する意見にあたるのであれば、ちょっとアンフェアではないかと思われます。

その拡張コントロールに "特殊な機能" が含まれる場合は、コントロール自体を分けざるを得ないですね。そうではなくデータだけを出したい、データだけを取得したい場合はああなるという話だったはずです。質問者が提示してきた情報はその程度のものだったはずです。それがいつの間にか四方八方に広がりここまで広がってしまうと、ケースバイケースと言ったほうが賢明なのは自明です。

私も話を広げた張本人であることは隠すつもりはないのですが、質問者からの情報から推測可能、未来予測可能、あるいは改善すべき箇所以外に話を広げたつもりはないです。どちらかというと、保守性の話でした。また勝手に推測しつつも、それについては明示化したつもりです。勝手ながらも明示化して広げた場合は、最悪な場合デムパ扱いを受けるだけですが、暗黙的に広げられると土俵が違うというか、何と言うか話が噛みあわないですね。

で、もちろん、R・田中一郎さんは当初から前提がそこまではっきりしていないことをわかっていて、ケースバイケースと言っていたのでしょう。それは理解しています。ただ、向こうでれいさんが指摘していたように、実際のところ 「どのケースが "主張している意見" になるのよ。」 という部分の説明がなされないまま 「ケースバイケース」 と言っても、意味を見出すことができないということです。

どうも、まとめてみると、意見はそれほど食い違っているわけでないというところですね。なーんか、ちょっとがっくりです。

私は、質問者の状況を "勝手に" 推測してこの方が良い的案を勝手にジャブ打ちで出した。 → 拡張コントロールの意見が出てきた → 私は "今回は" 適さないと見て反論した → 各 Blog で記事が作られた (しかし、スレッドの条件とは違ったコンディションで展開された。だからこそ Blog で書いたのだと思われる) → 私はコンディションの違いを意識せず、そのまま反論 → その反論に対して 「こういう場合は~」って、この時点で気付きました。良く読めば行間からわかりそうですが、私には読み取れませんでした。日本語が下手ですから... ごめんなさい。それと、途中の Blog のコメントをすっ飛ばさなければ良かったと後から読んで思いました。

# re: 部品化する場合としない場合(その2) 2007/06/15 15:28 じゃんぬねっと

しまった... orz

> 記事としては良いと思いますが、もしこれが私に対する意見にあたるのであれば、

そうでない場合と想定した返答を書くのを忘れてしまいました。答えさせて頂きます。

> では、都道府県を選択するコンボボックスが大量に必要になった場合はどうでしょうか?
> どの方法を使いますか?

アセンブリ間の関係によって変わるのもさることながら、規模によって変わります。カスタム コントロールの数が増えるようであれば、プロパティでの実装も考えますが、グルーピング化できるかどうかでもまた変わりますね。

また、データの出し入れだけが目的かどうかで変わります。今回は機能は書かれていないので、ほとんどの場合は 1 になりますね。バインドする処理というか、データだけ引き出すようにします。そのデータは他でも絶対に使いますから。

大量に必要となった場合というのは、複数のアセンブリでという意味なのでしょうけど、どのみちテストですぐわかることですから、ポトペタ対応とそれほど変わらないデータのみ共有で行きます。

> しかし、このような処理が複数のフォームで必要になった時、これらはユーザーコントロールにしても良いと思います。

その通りです。向こうにも書きましたが、ダイアログ ベースか複合コントロールになるでしょう。ちなみに、最近は "ユーザーコントロール" と "カスタム コントロール" という文言をあまり使わないようにしています。それは何故でしょう?

> テキストボックスは、ANKの16バイトの入力制限付き、更に商品マスターの存在チェックまでしなくてはならない。
> 入力された文字列は、有効なら黒色、無効なら赤色表示。
> 無効状態なら、他の入力ボックスのフォーカスに移動できない。
> (つい先日、似たようなものを作ったばかりです)
>
> どの方法を使いますか?
> 1. 毎回プロパティに設定、イベントも記述。
> 2. 入力規則の下請けメソッドを作って共通で呼びまわす。
> 3. 品番入力ボックスをテキストボックスから拡張。
> 4. その他。
>
> 僕はやっぱり品番入力ボックスを作りますね。
> ちなみに、品番入力ボックスの右に「参照」ボタンを付けて、品番検索ダイアログボックスが開くように機能追加した時に、とっても楽でした。

これは決められないですね。なぜなら、

> テキストボックスは、ANKの16バイトの入力制限付き、更に商品マスターの存在チェックまでしなくてはならない。

なぜ、[strong]テキストボックスが[/strong] "更に商品マスターの存在チェックまでしなくてはならない" のでしょうか。前提条件から反対したいので決められないです。

エラーはエラーとしてエラー検証用のロジックを共通化します。数が多いのであれば Validation 機能のコンポーネントを作って対応するという方法を取るかもしれません。そういう層を意識した共通化・共有化もあります。何もかもコントロールにすれば良いとは私は思いません。場合にもよりますが、今回の例では、コンポーネント化くらいしかやらないと思います。

# re: 部品化する場合としない場合(その2) 2007/06/15 23:50 Kazuki

意義あり!!
> 素敵だし爽やかRさんは、馬鹿のひとつ
素敵だし爽やかの部分です!!

# re: 部品化する場合としない場合(その2) 2007/06/17 0:39 通り*

部品って、作る人と使う人と保守する人が同じ場合、と、使うだけでいい場合、とでも、見方がかわってくるかなぁって思いました。
作ったり保守のこと考えると、私の場合、コントロール化は二の足を踏んじゃいますが、同じプロジェクトの人が品番入力ボックス作ってくれたら、私はよろこんで使うかな。
#範囲を広げすぎって怒らないでくださいね(^-^;ひとつのケースということで。。

>意義あり!!
そうですか?そのすぐ後のところ「ケースバイエース」ですよ。なんかとっても素敵な雰囲気ですよね!
公開していただいたRさんのセッション、これから見ますね(ワク
見た後は私も気持ち変わるのかなw

# re: 部品化する場合としない場合(その2) 2007/06/17 15:59 じゃんぬねっと

ああ、誤解されそうだったので一応再度明示させて頂きますが、
反論でなければ、一向に広げていって構わないと思いますよ。
ここは私のスペースでもないですし、私がとやかく言うことではないです。

# re: 部品化する場合としない場合(その2) 2007/06/18 19:36 R・田中一郎

trapemiya さん

>部品化する場合、汎用的なものと、あるプロジェクトに特化しているものと2種類あるんじゃないでしょうか?

汎用的なものと、プロジェクトに突破しているものは、保存するプロジェクトも変わってきますね。

>汎用的ではなくプロジェクトに特化している場合の部品化は、保守を含めトータルで工数削減になるかどうかだと思います。ビジネスロジックを入れることで逃げれるのであれば、部品化するまでもないと思います。

全く仰る通りだと思います。

>TableAdapterはある種の部品化だと思うのですが、汎用的ではなく、そのプロジェクトに特化し、工数減を目的としていると思います。

TableAdapter は、デザイナが吐き出してくれるものとしては便利ですね。
自分で最初から作るのは億劫ではありますが、それでも便利な場合もありますし・・・

>結論から言えば、ケースバイケースですね。

そういうことになるのでしょうね。

-----------------------------------------------------
じゃんぬねっと さん

>ちょーっと範囲を広げすぎかなぁと思います。記事としては良いと思いますが、もしこれが私に対する意見にあたるのであれば、ちょっとアンフェアではないかと思われます。

最初は、じゃんぬねっとさん向けに書いていたのですが、途中で、僕の言うところのケースバイケースの内容について明確に示していなかったように感じました。
そして、それらをきちんとまとめることにしました。

従って、既にじゃんぬねっとさんに対するものではなくなっています。

>どうも、まとめてみると、意見はそれほど食い違っているわけでないというところですね。なーんか、ちょっとがっくりです。

大きくは食い違っていないのかもしれませんが、微妙に違う部分はありそうですね。
例えば、じゃんぬねっとさんの「そうでない場合と想定した返答」の部分とか。

>した。良く読めば行間からわかりそうですが、私には読み取れませんでした。日本語が下手ですから... ごめんなさい。それと、途中の Blog のコメントをすっ飛ばさなければ良かったと後から読んで思いました。

あ、やっぱりすっ飛ばしていたんですね。

>そうでない場合と想定した返答を書くのを忘れてしまいました。答えさせて頂きます。

これは、僕にとって、とても勉強になりました。
ありがとうございました。

-----------------------------------------------------
Kazuki さん

>意義あり!!

ありがとうございます。
こういう細かいところに突っ込んでくれる人が欲しかったんです。

-----------------------------------------------------
通り* さん

>作ったり保守のこと考えると、私の場合、コントロール化は二の足を踏んじゃいますが、同じプロジェクトの人が品番入力ボックス作ってくれたら、私はよろこんで使うかな。

便利ですもんね。
保守の面では大変かもしれませんが、僕の前提では大量に用いている場合になるので、品番の入力に関する仕様が変われば、そのコントロールのみ修正すれば良いようにしておくと考えても良いのではないかと思います。

>公開していただいたRさんのセッション、これから見ますね(ワク

実は僕も見ました。

# re: 部品化する場合としない場合(その2) 2007/06/18 21:24 じゃんぬねっと

こら、このあたりは無視かw

> ちなみに、最近は "ユーザーコントロール" と "カスタム コントロール"
> という文言をあまり使わないようにしています。それは何故でしょう?

あと下記は完全な揚げ足取りなので、

> なぜ、[strong]テキストボックスが[/strong] "更に商品マスターの存在チェックまで
> しなくてはならない" のでしょうか。前提条件から反対したいので決められないです。

そういう意味で言ったのではないという反論が帰ってくるのかと思っていました。

> エラーはエラーとしてエラー検証用のロジックを共通化します。数が多いのであれば
> Validation 機能のコンポーネントを作って対応するという方法を取るかもしれません。
> そういう層を意識した共通化・共有化もあります。何もかもコントロールにすれば良いとは
> 私は思いません。場合にもよりますが、今回の例では、コンポーネント化くらいしかやらないと思います。

このあたりは思想の問題かもしれないけど、R・田中一郎さんはまだ UI を持たないコンポーネントの実装はやったことないんじゃないかなぁと思って書きました。上から目線気味になってしまいますが、もしやったことがないなら面白いのでいろいろ考えてみてください。2.0 では不要になってしまいましたが、1.1 時代に Validation 系のコンポーネントを使って一括エラーチェックをしていました。ErrorProvider と合わせると超協力でした。

# re: 部品化する場合としない場合(その2) 2007/06/20 0:32 Kazuki

じゃんぬさん
> 2.0 では不要になってしまいましたが、
コメントに食いついてごめんなさい!
ここらへん2.0で何か便利なものが追加されたんですか?

# re: 部品化する場合としない場合(その2) 2007/06/20 10:30 じゃんぬねっと

ValidateChildren メソッドとかですね。
これ単体だと単純なサマリでしかありませんが、ErrorProvider と連携すると良いです。
カスタマイズを進めていくとどうしても、拡張コントロールになったりすることもありますが。

# re: 部品化する場合としない場合(その2) 2007/06/20 16:08 R・田中一郎

じゃんぬねっと さん

> ちなみに、最近は "ユーザーコントロール" と "カスタム コントロール"
> という文言をあまり使わないようにしています。それは何故でしょう?

これはミニクイズになっていたんですね。
気づきませんでした。

答えは・・・わからないですね。
ユーザーコントロールとカスタムコントロールの意味は厳密に言うと違うからでしょうか?
ユーザーコントロールもカスタムコントロールに含まれるように思います。

>そういう意味で言ったのではないという反論が帰ってくるのかと思っていました。

反論すると、ショックで咳込んでしまうんじゃないかと思ったのです(嘘です。でも心配してたんですよ)

> エラーはエラーとしてエラー検証用のロジックを共通化します。数が多いのであれば
> Validation 機能のコンポーネントを作って対応するという方法を取るかもしれません。
> そういう層を意識した共通化・共有化もあります。何もかもコントロールにすれば良いとは
> 私は思いません。場合にもよりますが、今回の例では、コンポーネント化くらいしかやらないと思います。

普通に勉強になりました。

>R・田中一郎さんはまだ UI を持たないコンポーネントの実装はやったことないんじゃないか

UIを持たないコンポーネントとは、タイマーとかテーブルアダプターとかバックグラウンドワーカーのことでしょうか?
これらは、よくネタにしていますが。

>上から目線気味になってしまいますが、

.NET の師匠が何を謙虚なことを仰いますやら。
(というか、キャラが違いすぎて逆にガクブルなんですけど)

>もしやったことがないなら面白いのでいろいろ考えてみてください。

はい。ありがとうございます。

------------------------------------
Kazuki さん

おおっ、さすが。
いい質問ですね。
僕も勉強になりました。

# re: 部品化する場合としない場合(その2) 2007/06/20 19:29 じゃんぬねっと

> 答えは・・・わからないですね。

基本コントロール ・・・ Windows Forms などに含まれるコントロール
拡張コントロール ・・・ 基本コントロールから継承したコントロール
複合コントロール ・・・ UserControl から継承したコントロール
カスタム コントロール ・・・ System.Windows.Forms.Control から継承したコントロール
ユーザーコントロール ・・・ 非常にあいまい。人によっては拡張、複合、カスタム コントロールの総称とする人もいる。UserControl だけを示す人もいる。

これでわかるでしょうか。カスタム コントロールでさえも非常にアバウトです。

> UIを持たないコンポーネントとは、タイマーとかテーブルアダプターとか
> バックグラウンドワーカーのことでしょうか?
> これらは、よくネタにしていますが。

自作したことはないのでしょうか? という意味です。

# re: 部品化する場合としない場合(その2) 2007/06/21 14:14 R・田中一郎

じゃんぬねっと さん

>これでわかるでしょうか。カスタム コントロールでさえも非常にアバウトです。

なるほど。
だから、そういう言葉を使わないということですね。

>自作したことはないのでしょうか? という意味です。

びみょーですね。
あるような無い様な。
プロジェクトに、コンポーネントを追加したことは何度もあります。
で、ポトペタして作る訳ですが、この作り方は実は嫌いなんですよね。

# re: 部品化する場合としない場合(その2) 2007/06/21 17:26 Orator

> 都道府県を選択するコンボボックスが大量に必要になった場合
私の場合は、IExtenderProvider (と ISupportInitialize)を実装したコンポーネントを
作って、それを ComboBox / ListBox に割り当てる…という実装にしてるかな。

同じフォーム上に、都道府県コンボが複数必要になった場合でも、データの取得動作を
一回に纏められるし、"ComboBoxを継承したクラス" に対しても流用できるということで。

# re: 部品化する場合としない場合(その2) 2007/06/21 17:46 R・田中一郎

Orator さん

>私の場合は、IExtenderProvider (と ISupportInitialize)を実装したコンポーネントを
作って

これは、いいとこ取りな方法ですね。
僕も真似しようかな。

# re: 部品化する場合としない場合(その2) 2007/06/22 11:25 R・田中一郎

じゃんぬねっと さん

>自作したことはないのでしょうか? という意味です。

いま思い出しました。
MySQL 系データベースの TableAdapter はデザイナの自動生成ではなくて、全部自分で書いてます。
・・・って、もう見てないんでしょうね。

# re: 部品化する場合としない場合(その2) 2007/06/22 17:22 じゃんぬねっと

フィードにあがってくるのでまだ見ていますよ。

コンポーネント自体をですか?
アダプタから吸い上げるところだけという例なら良く見ますけど。。。

# re: 部品化する場合としない場合(その2) 2007/06/25 14:42 R・田中一郎

じゃんぬねっとさん

>フィードにあがってくるのでまだ見ていますよ。

見ていたんですね。

>コンポーネント自体をですか?

public partial class TableAdapterBase : Component{
:
ずらずら
:
}

という感じに、HogeHogeTableAdapter をずらずら書いています。

>アダプタから吸い上げるところだけという例なら良く見ますけど。。。

アダプタから吸い上げる?

タイトル
名前
Url
コメント