لقد قمت مؤخرًا بفرز مواصفات الشركة، ومن بينها أن "عدد معلمات الوظيفة يجب ألا يتجاوز 4" كان مثيرًا للجدل إلى حد ما أثناء الترقية. إذا كان من الممكن إكمال المهمة، فكلما قل عدد المعلمات، كان ذلك أفضل في حد ذاته مثير للجدل، ولكن القيام بذلك يمكن أن يسبب صعوبات عند البرمجة، وهناك جدل حول ما إذا كان الأمر يستحق ذلك. أعتقد أنه من المفيد القيام بذلك لتسهيل الأمر على الأشخاص الذين يستخدمون الوظائف، أما بالنسبة للصعوبات في البرمجة، فغالبًا ما يكون ذلك لأننا لسنا على دراية ببعض طرق تقليل المعلمات، وإليك بعض الملخصات كمرجع لك:
1. استخدم الهياكل لتغليف المعلمات
مثال: إضافة مستخدم
نص الوظيفة الأصلية: AddUser (اسم مستخدم السلسلة، كلمة مرور السلسلة، عنوان السلسلة، هاتف السلسلة، عمر int)
إعادة البناء: إضافة فئة مستخدم:
مستخدم الطبقة
{
سلسلة عامة اسم المستخدم {مجموعة؛
كلمة مرور السلسلة العامة {مجموعة؛
عنوان السلسلة العامة {مجموعة؛
سلسلة الهاتف العامة {احصل عليها}
العمر العام {احصل عليه}
}
تغيير AddUser إلى: AddUser(مستخدم مستخدم)
المشاكل: إذا لم يتم استخدام الفئة المضافة في مكان آخر، فغالبًا ما نشعر أنها لا تستحق العناء. في هذا الوقت، يمكننا التفكير في استخدام فئات مجهولة لتغليف المعلمات.
2. استخدم السمات لاستبدال المعلمات
إذا تم وضع أسلوب AddUser في 1 في فئة المستخدم، فيمكن حذف معلمات المستخدم في أسلوب AddUser في بعض الأحيان قد تتم إضافة بعض السمات لتقليل عدد المعلمات في بعض الطرق. في التصميم الموجه للكائنات، يجب أن تكون الكائنات مسؤولة عن نفسها، ويجب أن تكون المسؤوليات محددة بوضوح. قد يكون السبب وراء احتواء الطريقة على عدد كبير جدًا من المعلمات هو أن الطريقة مكتوبة في مكان لا ينبغي أن توجد فيه. يمكن لنموذج "خبير المعلومات" المذكور في مبدأ GRASP تقليل عدد المعلمات في كثير من الحالات.
مثال: تحويل الحساب
الوظيفة الأصلية: تحويل (حساب من، حساب إلى، أموال عشرية)
إعادة البناء:
شفرة
عملية نقل الطبقة العامة
{
حساب خاص من؛
حساب خاص إلى؛
عملية النقل العامة (الحساب من، الحساب إلى)
{
this.From = from;
this.To = to;
}
نقل الفراغ العام (المال العشري)
{
إذا (المال<من.المال)
{
From.Money = From.Money - المال؛
To.Money = To.Money + money;
// تحديث قاعدة البيانات
}
آخر
{
رمي استثناء جديد("تم تجاوز الرصيد");
}
}
}
ملحوظة: نمط خبير المعلومات هو المبدأ الأساسي للتصميم الموجه للكائنات عندما نقوم بتصميم كائنات (فئات)، إذا كان لدى الفصل جميع المعلومات اللازمة لإكمال مسؤولية معينة، فيجب تعيين هذه المسؤولية إلى هذه الفئة للتنفيذ. . في هذا الوقت، هذا الفصل هو خبير المعلومات المناسب لهذه المسؤولية.
3. استخدم الوظائف الخاصة
عند استدعاء وظيفة، لا نحتاج غالبًا إلى العديد من المعلمات التفاعلية، ولكن عندما نقدم المعلمات، نحتاج إلى توفير جميع الشروط. في هذا الوقت، يمكننا تصنيف الوظائف، وتغليف الوظائف الأكثر تعقيدًا على أنها خاصة، وكشف وظائف بسيطة. استدعاء هذه الوظائف المعقدة لإكمال الوظيفة. دعونا نلقي نظرة على تنفيذ طريقة TextBox في mvc:
شفرة
سلسلة ثابتة عامة TextBox(هذا HtmlHelper htmlHelper، اسم السلسلة، قيمة الكائن، IDictionary<string, object> htmlAttributes) {
return InputHelper(htmlHelper, InputType.Text, name, value, (value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
}
سلسلة ثابتة خاصة InputHelper (هذا HtmlHelper htmlHelper، InputType inputType، اسم السلسلة، قيمة الكائن، bool useViewData، bool isChecked، bool setId، bool isExplicitValue، IDictionary<string, object> htmlAttributes) {
إذا (String.IsNullOrEmpty(name)) {
طرح ArgumentException جديد (MvcResources.Common_NullOrEmpty، "name")؛
}
TagBuilder tagBuilder = new TagBuilder("input");
... ...
لكن في بعض الأحيان، من أجل منح المتصل أقصى قدر من المرونة، قد نكشف أيضًا عن التحميل الزائد للوظيفة الأكثر تعقيدًا.
4. الكلمة الأساسية المعلمات
يحدد أنه عندما يكون عدد المعلمات متغيرًا، يتم استخدام معلمة الأسلوب الخاصة بالمعلمة.
الاستخدام:
شفرة
الفراغ الثابت الرئيسي (سلسلة [] الحجج)
{
UseParams(1, 2, 3);
}
UseParams الفراغ العام الثابت (قائمة المعلمات int[])
{
لـ (int i = 0; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
}
هذه الطريقة لا تقلل في الواقع عدد المعلمات، ولكنها تعمل فقط على تبسيط نص الوظيفة.
5. استخدم الفئات المجهولة لتغليف المعلمات
المعرفة التحضيرية: دعونا نلقي نظرة على RouteValueDictionary أولاً
شفرة
الفراغ الثابت الرئيسي (سلسلة [] الحجج)
{
RouteValueDictionary r = new RouteValueDictionary(new { id=1,name="lfm"});
foreach (عنصر var في r)
{
Console.WriteLine("{0}:{1}"، item.Key, item.Value);
}
//Console.WriteLine();
}
نتيجة:
المعرف:1
الاسم: lfm
يمكن لـ RouteValueDictionary تخزين أسماء السمات وقيم السمات للمثيلات في القاموس.
تستخدم العديد من الأماكن في mvc هذه الطريقة لتمرير المعلمات.
على سبيل المثال: <%= Html.ActionLink("Details"، "Details"، new { id=item.id })%>
في نص أسلوب ActionLink، يتم استخدام RouteValueDictionary لتحليل الكائن المجهول ثم تجميعه على الرابط.