程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> ASP編程 >> ASP技巧 >> 控制參數個數的幾種方式

控制參數個數的幾種方式

編輯:ASP技巧

最近整理了一下公司規范,其中“函數的參數個數不宜超過4個”這一條在推廣的時候有些爭議,在能完成任務的情況下參數越少肯定越好,這本身沒什麼可爭議的,但這樣做可能會在編程時帶來困難,爭議點在是否值得這樣做。我覺得為了讓使用函數者更簡單這樣做還是值得,至於編程時的困難往往是因為我們不熟悉一些減少參數的方法,這裡總結幾條供大家參考:

1、使用結構來封裝參數

例子:添加用戶

原函數體:AddUser(string userName,string passWord,string address,string phone,int age)

重構:添加一個User類:

 

class User
    {
        public string UserName { get; set; }
        public string PassWord { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public int Age { get; set; }
    }

 

 

將AddUser改為:AddUser(User user)

存在的問題:如果添加的這個類沒有其他地方用,常常會覺得這樣做並不值得,這時我們可以考慮使用匿名類封裝參數的方法。

2、使用屬性來替換參數

如果將1中的AddUser方法置於User類中,那麼AddUser方法中的user參數都可以省掉了,有的時候可能為了減少某些方法的參數個數而添加某些屬性。面向對象設計中,對象應該自己負責自己,而且應該清楚定義責任。某個方法參數太多的原因可能是這個方法寫在了他不該存在的地方,GRASP原則中講的“信息專家”模式很多情況下可以減少參數的個數。

例子:帳戶轉賬

原函數:Transfer(Account from,Account to,decimal money)

重構:

 

代碼
public class TransferPRocess
    {
        private Account From;
        private Account To;
        public TransferProcess(Account from, Account to)
        {
            this.From = from;
            this.To = to;
        }
        public void Transfer(decimal money)
        {
            if (money<From.Money)
            {
                From.Money = From.Money - money;
                To.Money = To.Money + money;
               //更新數據庫
            }
            else
            {
                throw new Exception("超出余額");
            }
        }
    }
注:信息專家模式是面向對象設計的最基本原則,我們設計對象(類)的時候,如果某個類擁有完成某個職責所需要的所有信息,那麼這個職責就應該分配給這個類來實現。這時,這個類就是相對於這個職責的信息專家。

 

3、使用私有函數

調用某個函數時往往並不需要很多的交互參數,但我們提供參數時則需要提供所有的情況,這時我們可以把函數分類,將最復雜的函數封裝成私有的,而暴露出來的簡單函數調用這些復雜函數完成功能。我們來看看mvc中的TextBox方法的實現方式:

 

代碼
   public static string TextBox(this HtmlHelper htmlHelper, string name, object value, 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, string name, object value, bool useVIEwData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<string, object> HtmlAttributes) {
            if (String.IsNullOrEmpty(name)) {
                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 (var item in r)
            {
                Console.WriteLine("{0}:{1}", item.Key, item.Value);
            }
            //Console.WriteLine();
        }


結果:

id:1

name:lfm

RouteValueDictionary可以將實例的屬性名及屬性值存入到字典中。

mvc中很多地方使用這種方式傳遞參數。

比如: <%= Html.ActionLink("Details", "Details", new { id=item.id })%>

ActionLink方法體中就是使用RouteValueDictionary將匿名對象進行了分解,然後將其拼裝到鏈接上。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved