最近会社の仕様を整理したのですが、その中で「関数のパラメータの数は4つを超えてはいけない」というのは、業務を遂行できるのであれば、それ自体が良いわけではありません。物議を醸していますが、そうすることでプログラミング時に困難が生じる可能性があり、その価値があるかどうかについては議論があります。関数を使用する人にとって、これを行うことは価値があると思います。プログラミングの難しさに関して言えば、多くの場合、パラメータを削減する方法に慣れていないことが原因です。参考までに、以下にいくつかの概要を示します。
1. 構造体を使用してパラメータをカプセル化する
例: ユーザーの追加
元の関数本体: AddUser (文字列 userName、文字列パスワード、文字列アドレス、文字列電話番号、整数)
リファクタリング: User クラスを追加します。
クラス ユーザー
{
パブリック文字列ユーザー名 { セット;
パブリック文字列パスワード { セット;
パブリック文字列アドレス { セット;
パブリック文字列電話 { セット;
public int 年齢 { セット;
}
AddUser を次のように変更します: AddUser(ユーザー user)
問題: 追加したクラスが他の場所で使用されていない場合、現時点では、パラメータをカプセル化するために匿名クラスを使用することを検討できます。
2. 属性を使用してパラメータを置き換える
1 の AddUser メソッドが User クラスに配置されている場合、一部のメソッドのパラメーターの数を減らすために、AddUser メソッドのユーザー パラメーターを省略できる場合があります。オブジェクト指向設計では、オブジェクトはそれ自体に責任を持ち、責任は明確に定義される必要があります。メソッドのパラメータが多すぎる理由は、メソッドが存在すべきではない場所に記述されている可能性があります。GRASP 原則で言及されている「情報エキスパート」モデルにより、多くの場合パラメータの数を減らすことができます。
例:口座振替
オリジナル機能:振替(口座元、口座先、小数通貨)
リファクタリング:
コード
パブリック クラス TransferProcess
{
プライベートアカウントから;
プライベートアカウント宛先;
公的送金プロセス(アカウントの送信元、アカウントの送信先)
{
this.From = から;
this.To = に;
}
公的無効送金(小数通貨)
{
if (お金<From.お金)
{
From.Money = From.Money - お金;
To.Money = To.Money + お金;
//データベースを更新する
}
それ以外
{
throw new Exception("残高を超過しました");
}
}
}
注: 情報エキスパート パターンは、オブジェクト指向設計の最も基本的な原則です。オブジェクト (クラス) を設計するとき、クラスが特定の責任を完了するために必要なすべての情報を持っている場合、その責任は実装のためにこのクラスに割り当てられる必要があります。 。この時点で、このクラスはこの責任に対応する情報の専門家です。
3. プライベート機能を使用する
関数を呼び出すとき、多くの対話型パラメーターは必要ありませんが、パラメーターを指定する場合は、すべての条件を指定する必要があります。この時点で、関数を分類し、最も複雑な関数をプライベート関数としてカプセル化して、単純な関数。これらの複雑な関数を呼び出して関数を完了します。 mvc での TextBox メソッドの実装を見てみましょう。
コード
public static string TextBox(this HtmlHelper htmlHelper、文字列名、オブジェクト値、IDictionary<string, object> htmlAttributes) {
return InputHelper(htmlHelper, InputType.Text, name, value, (value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
}
private static string InputHelper(this HtmlHelper htmlHelper、InputType inputType、文字列名、オブジェクト値、bool useViewData、bool isChecked、bool setId、bool isExplicitValue、IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(名前)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}
TagBuilder tagBuilder = new TagBuilder("input");
……
ただし、呼び出し元に最大限の柔軟性を与えるために、最も複雑な関数のオーバーロードを公開する場合もあります。
4.paramsキーワード
パラメータの数が可変の場合、パラメータのメソッド パラメータが使用されることを指定します。
使用法:
コード
static void Main(string[] args)
{
UseParams(1, 2, 3);
}
public static void UseParams(params int[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
}
この方法では実際にパラメータの数は減りませんが、関数本体が簡素化されるだけです。
5. 匿名クラスを使用してパラメータをカプセル化する
準備知識: まずは RouteValueDictionary を見てみましょう
コード
static void Main(string[] args)
{
RouteValueDictionary r = new RouteValueDictionary(new { id=1,name="lfm"});
foreach (r の var item)
{
Console.WriteLine("{0}:{1}", item.Key, item.Value);
}
//Console.WriteLine();
}
結果:
ID:1
名前:lfm
RouteValueDictionary はインスタンスの属性名と属性値を辞書に格納できます。
MVC の多くの場所で、このメソッドを使用してパラメータを渡します。
例: <%= Html.ActionLink("詳細", "詳細", new { id=item.id })%>
ActionLink メソッド本体では、RouteValueDictionary を使用して匿名オブジェクトを分解し、リンク上にアセンブルします。