- PR -

メソッドの設計方法について

投稿者投稿内容
Tol
常連さん
会議室デビュー日: 2004/07/16
投稿数: 27
投稿日時: 2007-01-26 01:22
VB(VCでもC#でもよいのですが)での設計方法について質問があります。

現在ある情報を取得して返すメソッド(仮にGetInfoメソッド)を
作成しようとしています。
このメソッドは入力としてAを受け取って、ある情報Bを取得し返す
必要があります。
ただし、このメソッドはエラーを返すこともあります。
さらにそのエラーは複数の原因(仮にEとF)があるため、区別できるようにしなければなりません。

ここでエラーについては、通常例外として返すことができると思いますが、
業務の都合上例外の使用はできません。
そのため、これらの情報(B、正常かエラー(EかF))を返すためには、
以下のメソッドが考えられると思っています。

@Infoクラスは、Bとエラーコード(正常、EまたはFが格納)を取得するデータクラス
 ※InfoクラスのエラーコードがEまたはFの場合は、Bの値は意味をもたない。

サンプル:
Function GetInfo(ByVal A As xxx) As Info

Aエラーコードは戻り値として返し、情報Bは参照渡しで渡してセットしてもらう

サンプル: 
Function GetInfo(ByVal A As xxx, ByRef B as xxx) As errorCode

Bすべて参照渡しでもセットしてもらう

サンプル:
Sub GetInfo(ByVal A As xxx, ByRef B as xxx, ByRef errorCode As xxx)


一般的な設計としてはどのインタフェースとするのがいよいのでしょうか?
100%の解はないのかもしれませんが、皆様の考えを教えていただければ
と思っています。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-01-26 07:35
4)
エラーが発生した場合には、エラーが発生したことを示す値(たとえばNull)を返し、詳細なエラーの種別に関しては別のメソッド(たとえばGetLastError)を用いて取得する。

サンプル:
Function GetInfo(ByVal A As xxx) As Info


Infoに本来の機能とは全く関係ないエラーコードをとしての意味を内包させることは感心しない。したがって1)は却下。3)の実装は呼び出す側で必ずエラーを格納するための変数を用意する必要がある。呼び出しのためのコーディング量が増えるので却下。

現実によく見かけるのは2)か4)だと思う。

でも、さらに言うなら、業務の都合上構造化例外を使ってはならない理由を思いつかない。構造化例外を使うことによってエラー時の例外処理の記述を相当に減らすことができるので積極的に利用すべき。実行速度が低下することを理由に挙げる人がいるが、だったらVB.NETを選択している時点で間違えている。C++では移植性の観点から構造化例外を使わない場合もあるが、VB.NETなら移植性が問題になる事もない。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2007-01-26 09:12
引用:

lamさんの書き込み (2007-01-26 01:22) より:

一般的な設計としてはどのインタフェースとするのがいよいのでしょうか?



僕は、戻り値はメソッド名の左に置くのが好きなので、欲したい値と、エラー情報を Property として実装したオブジェクトを生成して返す方法を使うと思います。

ただし、一般的には例外処理を使うので、その他の方法は一般的にはならないように思いますが。


_________________
R・田中一郎 -  R.Tanaka.Ichiro’s Blog
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-01-26 09:58
引用:

lamさんの書き込み (2007-01-26 01:22) より:

(1) Infoクラスは、Bとエラーコード(正常、EまたはFが格納)を取得するデータクラス
 ※InfoクラスのエラーコードがEまたはFの場合は、Bの値は意味をもたない。

サンプル:
Function GetInfo(ByVal A As xxx) As Info


これは、戻り値 Info とは関係ない情報が紛れるので使わないです。
このあたりは、甕星さんと同意見ですね。

ちなみに Get ではなく Execute 系のメソッドであれば、エラーを別のプロパティに置くパターンがあり得ます。

引用:

(2) エラーコードは戻り値として返し、情報Bは参照渡しで渡してセットしてもらう

サンプル:
Function GetInfo(ByVal A As xxx, ByRef B as xxx) As errorCode


これは、FCL 2.0 の [ValueType]::TryParse メソッドに倣ったものですね。

戻り値は単純に bool としたいところですが、今回のように詳細が欲しい場合は、
列挙体ではなく、エラーを示すクラスのインスタンスにします。

それでもあまり使いたくないパターンですが、この 3 つの中では 1 番良いと思います。
しかし、この場合は、Get ~ という名称は改変すべきかもしれません。
(戻り値が Info ではないので)

引用:

(3) すべて参照渡しでもセットしてもらう

サンプル:
Sub GetInfo(ByVal A As xxx, ByRef B as xxx, ByRef errorCode As xxx)


これは、絶対に使わないです。
参照渡しで結果を受け取るより、戻り値で結果を受け取った方が良いです。

別途でエラー取得用のメソッドを用意するパターンは、
理解が 'クラスの仕様に及ぶ' ので、個人的には (2) を選択するでしょうか。

しかしながら、GetInfo メソッドが Try 系のメソッドではないので、(Get できない == 例外)
結論としては、やはり例外を Throw するのが正しい方法でしょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-01-26 10:29
他の方もおっしゃられているように、.NETなら本来は例外処理を使うべきところだと思います。
外部とのインタフェースの問題等で、本当に仕方ない場合もあるとは思いますが、
可能ならば例外処理を使うように、設計を見直すことも検討してみてはいかがでしょうか?

本当に例外を使えないという前提で上記の候補から選ぶなら
私は、通常は2番を採用すると思います。
甕星さんのおっしゃる4番の方法の方が本来の設計な気もするのですが、
戻したい値が値型の場合、エラーが発生したことを示す値を定義するのが面倒なので
私は2番にすることが多いです。

あとは、少し論点がずれるかも知れませんが、
取得したいデータが複雑なものであれば、
データと、データを取得するメソッドを含めたクラスを作るという設計もあるかと思います。
この設計ならエラー情報がそのクラスに含まれても違和感はないと思います。

コード:

Public Class Info

    'ここでフィールドとプロパティを宣言する(エラー情報含め)

    Public Function GetData() As Boolean

        'ここでデータを取得して内部フィールドに格納する
        'エラーの場合はエラー情報の設定も行う

        '正常に取得できた場合はTrue, エラーの場合はFalseを返す
    End Function

End Class


取得したいデータが単純な値(数値1個だけとか)の場合は、大袈裟な感じになってしまいますが…
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2007-01-26 10:54
「業務の都合上例外の使用はでき(ない)」というのが具体的にどういうことなのか知りたいですね。
あと、EとFが正しい運用をしている時にも発生しうるものなのかどうかも。
とりこびと
会議室デビュー日: 2006/10/05
投稿数: 5
投稿日時: 2007-01-26 11:03
経験とか一般的とか持ち合わせていませんので逆にご意見伺いな意味もこもってしまいますが、考えてみました。質問された方の投稿の前提であくまでGetInfoという名前のメソッドであるなら、

コード:

Function GetInfo(ByVal a As xxx, ByRef errorCode As ErrorCode) As Info


GetInfoを呼び出した時にはやっぱりInfoが返ってきてほしいです。
Tol
常連さん
会議室デビュー日: 2004/07/16
投稿数: 27
投稿日時: 2007-01-26 11:25
ご返信ありがとうございます。
大変参考になります。

引用:

「業務の都合上例外の使用はでき(ない)」というのが具体的にどういうことなのか知りたいですね。
あと、EとFが正しい運用をしている時にも発生しうるものなのかどうかも。



確かに例外を使わないことを不可解に思われるのはもっともだと思います。個人的にもなぜという思いはあります。
理由なのですが、現在のシステムが複数の言語(C(Unix),Java、.NET(VB, C#))で構成されていることにあります。
今私が作ろうとしているもの(GetInfo)は、これらのすべての言語で提供する必要があります。
作るにあたって、扱いやすいようにインタフェースを統一してくれという話があり、
例外のないCで例外を模倣することは難しいのため、他の言語をC風にあわせようと
話になっています。
もちろん言語が違うのだから多少の違いはでてもいいじゃないかという意見はあると思いますが、みんながみんな言語がわかる人でもなく、政治的理由でどうにも・・・というのが正直なところです。

また、EとFは正しい運用を行っていても出る可能性があります。
これは出る、出ないで設計が変わるものなのでしょうか?

またもう1つ別の疑問がでてきました。
ByRefなのですが、これは使わずByValでオブジェクトを渡して、そのプロパティで
セットするようにしたほうがいいのではないかとう意見があったのですが、
どうなのでしょうか?

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