簡體   English   中英

僅創建采用該類型實例的靜態方法是不明智的做法

[英]Is it bad practice to only create static methods that take instances of that type

以此類為例:

public class Account
{
    public string Code { get; set; }
    public string Description { get; set; }
    public DateTime CreatedOn { get; private set; }  

    public void Create()
    {
        // Invoke with new Account({...}).Create();
    }

    //Or

    public static void Create(Account account)
    {
        // Invoke with Account.Create(new Account({...}));
    }
}

這兩個Create()方法都將執行相同的操作,但是如您所見,它們的調用方式有所不同。 一種方法比另一種更好嗎? 有寫這樣的代碼的術語嗎?

在這種情況下,我建議您不要使用靜態方法,因為您應該創建很多帳戶,並且每個帳戶都有其自己的不同屬性。 但是我認為Create()方法沒有意義,因為您可以直接使用構造函數來設置帳戶。 所以這是我會怎么做:

public class Account
{
      public string Code { get; set; }
      public string Description { get; set; }
      public DateTime CreatedOn { get; private set; }  

      public Account()
      {
          Description = string.Empty;
          CreatedOn = DateTime.Now;
          //Code = ...
      }

      public Account(string Description)
      {
          this.Description = Description;
          CreatedOn = DateTime.Now;
          //Code = ...
      }
}

Ant,然后我將創建另一個類來管理帳戶:

class AccountsManagement
{
      public List<Account> Accounts
      {
           get;
           set;
      } 

      public AccountsManagement()
      {
           Accounts = new List<Account>();
      }

      //...   

      public void Create()
      {
           Accounts.Add(new Account();
      }

      public void Create(string Description)
      {
           Accounts.Add(new Account(Description);
      }

      //Or

      public void AddAccount(Account account)
      {
           Accounts.Add(account);
      }

      //Find(), Delete()...
}

因此,繼續演講不是壞習慣,而是使用靜態方法,但只有在適當時才使用它們。

總的來說,我不知道這是好事還是壞事。 但是,在您給出的示例中,我傾向於“不好的做法”(而且我無法想到將任何類型的實例傳遞給在該類型上聲明的靜態方法的任何有用的理由)。

當然,在您的示例中,您(IMO)正在創建一個不清楚的API。 我不確定是否;

  • Account.Create旨在為帳戶發出數據存儲請求(功能肯定屬於對象模型中的其他功能)
  • 是一種使用某些默認參數集創建Account實例的“便捷”方法(可以說在Account的構造函數中會更好)
  • 用作復制構造函數(在這種情況下,它應該是構造函數)
  • 是AccountFactory的廉價實現(在這種情況下,您應該建立工廠!)

另一個考慮因素是測試-靜態方法在對任何調用它們的內容進行單元測試時可能會帶來困難,因為它們可能不容易模擬或存根。

除了這些,從技術上講,這沒有天生的“錯誤”。 但是,它以其他方式影響您的設計(例如,由於它不是實例,因此無法訪問實例成員)。

因此,我認為這種方法可能會引起一些混亂,但是,它也可能完全適合您的情況!

如果該方法的靜態版本和實例版本都將執行相同的操作,那么我肯定會使用實例方法版本。 有幾個原因:

  1. 編寫更少的代碼 您是否願意不斷編寫Account.Create(accountObj); 或僅僅是accountObj.Create();
  2. 智能感知 當我有一個自定義對象時,我不記得自己使用的所有方法,通常可以幫助我鍵入accountObj. 並從下拉菜單中查看使用的方法。 如果使用靜態版本,則該方法將不會顯示,並且可能需要花費幾秒鍾的時間來記住如何使用/查找Account.Create()方法。
  3. 這是有道理的 如果您有一個可用於自定義對象的單個實例的方法,則它是一個實例方法。

以我的拙見,在實例上使用靜態版本的唯一原因是,您是否需要使Create()方法不能訪問帳戶對象的私有成員。

我可以想到使用諸如Create之類的靜態方法的唯一原因是,您將默認構造函數設為私有,並希望僅通過helper方法來控制實例的創建。
這種設計實際上是由Microsoft表達式樹框架使用的,其中您是通過表達式類的靜態方法創建實例的,但是它們之間還具有更復雜的抽象類層次結構

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM