簡體   English   中英

A方法是應該從對象獲取某些屬性還是只取對象?

[英]Should A method takes some properties from an object or just take the object?

例如

        int GetNum(int x, int y)
              {
                  return x+y;
               }

然后打電話

         z= GetNum(myobject.x, myobject.y);

要么

         int GetNum(ClassA myobject)
              {
                  return myobject.x+myobject.y;
               }

然后打電話

          z = GetNum(myobject);

傳入屬性值以減少類之間的耦合。 在這種情況下,定義GetNum的類不需要知道ClassA

最好減少類之間的耦合\\依賴關系,因為這會使您的設計更加靈活。 您在哪里為方法提供復雜類型,然后提供接口,以便您可以改變傳遞的特定實現。 這再次使您的設計更加靈活,更易於測試。

我遵循的一般規則就是這個。 該方法是否需要對象?,還是需要對象的屬性值? 后者使該方法更加可用(因為它不需要用戶創建具有這些屬性的任何類型的實例)。

你能做什么,提供一個過載(從而支持兩者):

int GetNum(int x, int y) { return (x + y); }
int GetNum(ClassA obj) { return GetNum(obj.X, obj.Y); }

問問自己該方法的可能用例是什么,然后詢問您是否確實需要傳入包裝值的實例。

考慮一下我可能有以下方法:

public void ProcessMessage(Result result)
{
  // Do something with Result.ReturnedMessage
  result.ReturnedMessage.Process(result.Target);
}

它接受理論Result類型的單個實例,但實際情況是,它只使用兩個參數,因此我們可以將其重新定義為:

public void ProcessMessage(Message message, Target target)
{
  message.Process(target);
}

現在,這可以使該方法在更多場景中可用,當然,您可以定義一個僅從ProcessMessage(Result)路由到ProcessMessage(Message, Target)等的重載。

另一方面,如果該方法構成接口定義的一部分:

void ProcessMessage(Result result);

您無法保證實現該方法的類型不僅需要訪問不僅僅是ReturnedMessageTarget屬性。

最重要的是,考慮你的用例,以及它如何適應更大的設計。 還要考慮面向未來......如何輕松地提升我們的理論Result類型?

作為腳注,這是一個非常類似的論點,關於使用專門類型或基類型傳遞值的位置,例如:

public void DoSomething(List<string> items);
public void DoSomething(IList<string> items);
public void DoSomething(IEnumerable<string> items);

在上面的示例中,您的方法是否正在執行任何明確需要List<string>類型的方法,或者它是否可以使用IList<string>接口定義...或者如果您根本不添加任何內容..接受一個怎么樣?而是IEnumerable<string>實例。 您對方法調用的專門化程度越低,它們的使用范圍就越廣泛。

我認為這很大程度上取決於你自己的編碼風格。

在我看來,如果該方法的目的與該對象相關聯,則該方法應該將對象作為參數。 例如,將對象的字段格式化為漂亮的文本字符串的方法應該將對象作為其參數。

在您的示例中,該方法與該對象並不真正相關 - 它可能需要任意兩個數字,它們不必包含在特定對象中以便工作,因此我認為該方法應該將屬性作為參數。

不過,我不認為你選擇哪種風格會有很大的不同。

在這種情況下,作為chibacity說GetNum不需要知道ClassA。 但是,您可能會考慮實際添加GetNum作為ClassA的方法,該方法調用GetNum傳遞適當的值。 它不一定寫,但如果你要做很多它可能有意義。

我認為,就像其他一切有趣一樣,答案是“它取決於”。

這個例子可能已經過分簡化,以提供足夠的背景來正確回答問題。 似乎有三種解決方案的方法:1)int GetNum(ClassA myObject){}
2)int ClassA.GetNum(){}
3)int GetNum(int a,int b){}

在過去,我會贊成選項2,使GetNum成為ClassA的成員。 GetNum的工作方式與調用者的業務無關,或者它從何處獲取信息,您(調用者)只想從ClassA對象獲取數字。 選項代碼需要知道ClassA的內容,所以這是不合適的,即使它只使用兩個getter。 如果我們對上下文了解得更多,那么可能選擇一個會更好。 我無法從這個問題中看出來。

對提高工作中代碼的可測試性非常感興趣,特別是遺留代碼。 除非已經有一個有用的單元測試框架,否則選項1和2需要ClassA的對象,並進行實例化以進行測試。 為了使代碼可測試(特別是如果ClassA很昂貴或實例化不切實際),我們一直在使用類似於選項3(或使其成為ClassA的靜態成員)。 這樣,您不需要實例化或傳遞難以制作的對象,並且您可以輕松添加完整的代碼測試覆蓋率。

一如既往,YMMV。

暫無
暫無

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

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