簡體   English   中英

優雅地設計一種具有2個重載的方法,一個重載一個對象,另一個不重載

[英]Elegantly designing a method with 2 overloads, one accepts an object the other doesn't

我需要設計一個方法,該方法可以將一個對象作為參數,如果沒有,則該方法必須自己創建一個新對象。

這是一個好方法嗎?

public void Method1(int companyId, int userId, int clientId)
{
     Method1(null, companyId, userId, clientId);
}
public void Method1(SpecialObject o, int companyId)
{
      if(o == null)
          o = new SpecialObject(userId, clientId);


}

擴大丹尼爾的答案,我經常使用這種模式:

public void Method1(int companyId, int userId, int clientId)
{
     Method1(new SpecialObject(userId, clientId), companyId);
}

public void Method1(SpecialObject o, int companyId)
{
    // if needed
    if (o == null)
    {
        throw new ArgumentNullException("o")
    }
    ...
}

我不會那樣做。 聽起來這超出了Method1的范圍/職責。 你為什么不能建立SpecialObject 之前調用Method1

您的代碼段不清楚。 在第一個替代中,調用未顯示的Method1替代。 在第二個覆蓋中,將userId和clientId傳遞給SpecialObject的構造函數,但不顯示在其中定義userId和clientId的位置。

無論如何,一些通用方法包括

  • 對參數進行排序,以使出現在更多替代中的參數優先定位,
  • 期望引用變量為非null(檢查並可能拋出ArgumentNullException),並且
  • 對於可以為null的參考變量,請創建一個不包含該變量的替代。

在我看來,這是一個完美的設計模式。

(我不知道您對“ o”的初始化是否有效,但這不重要)

在編寫單元測試時,我使用了類似的方法。

在正常(非測試)情況下,被測類將構造其自己的成員對象。 但是,如果合適的話,在測試中,我可以傳遞一個模擬或存根來使用。

例如,下面是一些C ++(我知道問題不關乎C ++,但該技術是可移植的)代碼來說明我所使用的技術。

class Foo {
public:
    Foo() : m_bar(new Bar()) {}//normal (non-test constructor)
    Foo(Bar* bar) : m_bar(bar) {} //constructor used when unit testing

private:
    Bar * m_bar;
};

這里的區別是,我將其與構造函數一起使用,而不是常規方法

這不是一個好的設計。 如果Method1是創建操作,則它應返回正在創建的對象。 如果是常規更新操作,則應要求事先創建對象。

最有可能的是,Method1的主體實際上應該是SpecialObject的方法(然后可能僅接收companyId)。

暫無
暫無

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

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