- PR -

業務システムのデザイン

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2006-05-19 13:27
抽象的な質問ですがよろしくお願いいたします。

Windowsアプリケーションで下記の画面構成とします。
・ログイン画面→メインメニュー画面→入力画面

仕様は以下の通りです。
・ログイン画面ではログインユーザ情報をRDBより取得します。
・メインメニュー画面ではログインユーザ情報により表示しないメニューがあります。
・入力画面も同じくログインユーザ情報により表示しないコントロールがあります。
・入力画面には入力コントロールが100個あったとします。
・登録ボタンにてRDBに登録します。
・(注)Form.vbにはSQLを書いてはいけない。
・RDBのデータはADOで取得し、DataSetへ更新する。

業務システムでは典型的なパターンだと思います。
これを綺麗にクラス分け(デザインパターン?)するとどうなるのでしょうか?
SEによってべた書きする場合もありますし、クラス分けにするけれどうまくいかず四苦八苦する場合もあります。
典型的なパターンである以上、何かベストな方法があるのではと思っています。


ちなみにクラス分けで失敗したパターンは以下のようなものでした。
・ログイン画面より入力した内容をログインManagerクラスのプロパティにセット。
・ログインManagerクラスがRDBから取得したデータをDataTableでログイン画面に戻す。
・ログイン画面よりメインメニューStartクラスのプロパティにユーザー情報をセットする。
・メインメニューStartクラスよりメインメニュー画面を開きプロパティにユーザー情報をセットする。
・メインメニュー画面はユーザー情報プロパティを元にメニューの不可を設定する。
・メインメニュー画面は入力画面Startクラスのプロパティにユーザー情報をセットする。
・入力画面Startクラスは入力画面を開き、プロパティにユーザー情報をセットする。
・入力画面は入力内容を入力画面Managerクラスのプロパティにセットし、RDBに登録する。

画面での入力内容が多いとクラスのプロパティにセットするだけでも非難の嵐でした。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-05-19 13:37
各クラスが次のフォームを開いたり、初期化をしたりするのでなく
フォーム間の動きを制御するクラスを別につくって
そいつに任せるっていうのはどうでしょうか
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-05-19 14:27
引用:

未記入さんの書き込み (2006-05-19 13:27) より:
画面での入力内容が多いとクラスのプロパティにセットするだけでも非難の嵐でした。


憶測も多くなりますが、作りこんだクラスの役割が、レイヤーとして薄いのかもしれません。RDB に直接アクセスしない、という規約を作ったので、RDB を使う代わりにそのクラスのプロパティーにアクセスしなければならないのだけど、RDB を使うのとさほど違いがないし、むしろクラスが余計に挟まっているため煩わしさが増えた、ということかもしれません。
以下、ひとつの考えであり、あまりこれに拘るつもりはないのですが、O/R マッピングなどまで使うほどではない、というシステム設計ならば、ほどほどのところで割り切ったほうが良いと思います。RDB が値オブジェクト(value object)に相当すると思いますので、RDB を使うならば、メソッドだけをクラスにしてフィールドは RDB をそのまま使うほうが無駄なレイヤーがなくて良いでしょう。すなわち、SQL 文だけをサブルーチンにしただけで、結局はクラスというものがほとんど登場しないような感じになります。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
たつごろー
ぬし
会議室デビュー日: 2004/10/25
投稿数: 496
投稿日時: 2006-05-19 15:31
引用:

ちなみにクラス分けで失敗したパターンは以下のようなものでした。
・ログイン画面より入力した内容をログインManagerクラスのプロパティにセット。
・ログインManagerクラスがRDBから取得したデータをDataTableでログイン画面に戻す。
・ログイン画面よりメインメニューStartクラスのプロパティにユーザー情報をセットする。
・メインメニューStartクラスよりメインメニュー画面を開きプロパティにユーザー情報をセットする。
・メインメニュー画面はユーザー情報プロパティを元にメニューの不可を設定する。
・メインメニュー画面は入力画面Startクラスのプロパティにユーザー情報をセットする。
・入力画面Startクラスは入力画面を開き、プロパティにユーザー情報をセットする。
・入力画面は入力内容を入力画面Managerクラスのプロパティにセットし、RDBに登録する。



いろいろと手はありますが、この情報だけの範囲でぱっと考えられることを列挙。

案1.Form自身でクラスです。ですから、xxxStartクラスにどれくらいの意味があるかよく
わかりません。状況によりますが、Formのクラスが、次のFormクラスを呼び出す形もありです。
案2.Formコントローラクラスを設ける。


引用:

画面での入力内容が多いとクラスのプロパティにセットするだけでも非難の嵐でした。


ユーザ情報をプリミティブ型単位に渡すということでしたら、非難はあるかと思います。
シングルトンにするとか、オブジェクト毎渡すとか、すればいいと思う。
どちらにせよ、ユーザ情報を持っているオブジェクトを、使うクラスは知っている、というもの
になります。


以下、参考になれば。

Application Block UIPの紹介
http://www.codeseek.net/dotNet/dotNetABUIP1.htm

画面遷移をどう実装するかのサンプル (かなり参考になりますが、重厚な実装です)
User Interface Process (UIP) Application Block - Version 2.0
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/uipab.asp

.NETでDBを扱う場合の考え方 (おぎわら@.NET道場Blogより)
http://blogs.yahoo.co.jp/ogiwara_hsk/10695409.html
この文章の中では、現時点で、
『.NETの一般的なケースでは「テーブル モジュール」がベター』
とされています。

Enterprise Library for .NET Framework 2.0
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/EntLib2.asp?frame=true

Microsoft patterns & practices
http://www.microsoft.com/japan/resources/practices/

_________________
たつごろー
codeseek
こみゅぷらす
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-05-19 15:58
僕なら、ユーザー情報クラスを作って、そのオブジェクトを各クラスが参照するよ
うにします。
ユーザーに関する情報が多くなった場合、確かにプロパティへ値を渡すのは大変か
もしれませんが、これは仕方がないかなぁ、という気がします。

入力フォームのコントロール・メニューの表示切替えの管理は、ひとつのクラスで
まとめた方が良いのか、メニューや入力フォーム単位でユーザー情報を参照させた
方が良いのかは、その性質によって変わる一概にどちらが良いとは言えないかも。
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2006-05-19 18:37
皆様ありがとうございます。

過去ログ「VB.NETとオブジェクト指向」が大変参考になりました。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=17461&forum=7
その中でもテーブルモジュールなどが出てきました。

たつごろー様
テーブルモジュールについて詳しく調べてみようと思います。

unibonさま
>SQL 文だけをサブルーチンにしただけで、結局はクラスというものがほとんど登場しないような感じになります。

はい。結局はこうなってきました。
ただSQLを組み立てる際、画面の入力内容を参照するためにサブルーチンの引数にフォームインスタンスを渡すのに抵抗がありました。
でもFormもクラスなので問題ないのしょうか?
画面系は継承やインタフェースなどの恩恵を感じますが
RDB系は従来のVBの方法がベターだということでしょうか?


田中一郎様、かるあ様
ユーザー情報のみをクラスにしても
RDB系ほかの部分(たとえば決算情報など複雑なJOINがいるものなど)で
クラスにできなくては、作成方法がわかりにくくなりませんでしょうか?
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-05-19 19:18
引用:

未記入さんの書き込み (2006-05-19 18:37) より:

ただSQLを組み立てる際、画面の入力内容を参照するためにサブルーチンの引数にフォームインスタンスを渡すのに抵抗がありました。


あまり良いことではないと思います。
引数には役割に応じて、必要な値を渡すようにしないと、後で何をしているのかがわかりにくくなりますし、サブルーチンの中でフォームオブジェクトの中身が変更されてし
まうかもしれませんよ?

引用:

未記入さんの書き込み (2006-05-19 18:37) より:

画面系は継承やインタフェースなどの恩恵を感じますが
RDB系は従来のVBの方法がベターだということでしょうか?


確か、プレゼンテーション層・ビジネスロジック層・データアクセス層に分けて考えるのが良いと、どこかに記事があったような・・・

スレ元のクラス分けは、そんなに悪いと思うのですが。
そもそも、プロパティに値を渡すのを面倒くさがっちゃあいけんですたい(どこの方言
?)
一番優先すべきことは、わかりやすいクラス構成にすることで、プロパティに値を渡すのを簡略化させることではないと思いますが。

引用:

未記入さんの書き込み (2006-05-19 18:37) より:

田中一郎様、かるあ様
ユーザー情報のみをクラスにしても
RDB系ほかの部分(たとえば決算情報など複雑なJOINがいるものなど)で
クラスにできなくては、作成方法がわかりにくくなりませんでしょうか?


ユーザー情報クラスの他に、相応しいクラスの中で決算情報取得用のメソッドを作れば良いと思いますが。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-19 22:22
引用:

未記入さんの書き込み (2006-05-19 13:27) より:

Windowsアプリケーションで下記の画面構成とします。
・ログイン画面→メインメニュー画面→入力画面


ですので、Form (クラス) はこの単位で良いですよね。

引用:

・ログイン画面ではログインユーザ情報をRDBより取得します。


実践されているように、ログイン情報を表すデータクラスを作るで良いと思います。

引用:

・メインメニュー画面ではログインユーザ情報により表示しないメニューがあります。
・入力画面も同じくログインユーザ情報により表示しないコントロールがあります。


関係ないところですが、これはむしろ逆にすべきですね。
「ユーザー情報によって、メニューやコントロールを非表示から表示にする」
ですよね。(予期せぬ事態が発生した場合の被害で考えています)

引用:

・(注)Form.vbにはSQLを書いてはいけない。


Form にビジネス ロジックを含めないでくださいということでしょうか。

SQL コマンドを集めた CommandText クラスを作るか、
または、データクラスに内包してしまうか、
あるいはストアド プロシージャでやりましょう。

引用:

ちなみにクラス分けで失敗したパターンは以下のようなものでした。
・ログイン画面より入力した内容をログインManagerクラスのプロパティにセット。
・ログインManagerクラスがRDBから取得したデータをDataTableでログイン画面に戻す。
・ログイン画面よりメインメニューStartクラスのプロパティにユーザー情報をセットする。
・メインメニューStartクラスよりメインメニュー画面を開きプロパティにユーザー情報をセットする。
・メインメニュー画面はユーザー情報プロパティを元にメニューの不可を設定する。
・メインメニュー画面は入力画面Startクラスのプロパティにユーザー情報をセットする。
・入力画面Startクラスは入力画面を開き、プロパティにユーザー情報をセットする。
・入力画面は入力内容を入力画面Managerクラスのプロパティにセットし、RDBに登録する。
画面での入力内容が多いとクラスのプロパティにセットするだけでも非難の嵐でした。


なぜ、色んな場面でプロパティにわざわざセットしているのでしょうか?
だから、利用者が理解できない (作成者以外は理解しがたい) 状況になっているのではないでしょうか?

クラス ライブラリ作成者は、サービス志向を意識する必要があります。
 「A をするするために、B をしなくてはいけない」
というルールは、他人にはわかりにくいものなのです。

Form の呼び出しに応じて引数で渡すなどして、強制した方がわかりやすいです。
そして、処理自体も引き継ぐことが容易なので、さらにわかりやすいです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

スキルアップ/キャリアアップ(JOB@IT)