2017-08-16 70 views
1

什麼是訪問的內部綁定類的更好,最優化的方式,在C#中訪問內部綁定類方法的更好方法是什麼?

  1. 通過公共財產

    class MyClass1 
    { 
        public MyClass2 m_myClass2 { get; set; } 
    
        public MyClass1(MyClass2 myClass2) 
        { 
         m_myClass2 = myClass2; 
        } 
    } 
    
    class MyClass2 
    { 
        public void MyClass2Method() 
        { 
         Console.WriteLine("Hello World!"); 
        } 
    } 
    
    class MyClass3 
    { 
        public void MyClass3Method(MyClass1 myClass1) 
        { 
         myClass1.m_myClass2.MyClass2Method(); 
        } 
    } 
    
  2. 通過方法調用

    class MyClass1 
    { 
        private readonly MyClass2 m_myClass2; 
    
        public MyClass1(MyClass2 myClass2) 
        { 
         m_myClass2 = myClass2; 
        } 
    
        public void MyClass1AccessMyClass2Method() 
        { 
         m_myClass2.MyClass2Method(); 
        } 
    } 
    
    class MyClass2 
    { 
        public void MyClass2Method() 
        { 
         Console.WriteLine("Hello World!"); 
        } 
    } 
    
    class MyClass3 
    { 
        public void MyClass3Method(MyClass1 myClass1) 
        { 
         myClass1.MyClass1AccessMyClass2Method(); 
        } 
    } 
    

調用方法MyClass2MethodMyClass2的最佳做法是什麼,通過類別MyClass3。在MyClass3中未引用MyClass2。

方式1方式2

+0

我建議在「方式2」的方向使用接口和giong,但使用接口而不是具體的類。 MyClass3並不在乎它是如何在MyClass1中完成的,它不需要關心(它將與「方式1」一起使用)。 – Fildor

+0

你能解釋一下Way 2比Way 1更適合嗎?或者至少有這樣一個解釋的參考? –

+0

您在詢問「更好」,「優化」和「最佳實踐」,所有這些都是基於意見的。你關心某個特定的方面嗎?這些類實際代表什麼?你對OO設計原理有什麼瞭解?你的研究表明了什麼? – CodeCaster

回答

4

你撞到稱爲Law of Demeter軟件的原則,這基本上是至少的知識,可能的(實際)

一般最好是隻訪問方法的原理在Myclass1上不知道任何其他類都存在。

更好的可能是通過一個接口取決於實際的上下文。

1

什麼,我在評論中寫道的一個例子:

interface DancesWithWolves 
{ 
    void DanceWithWolves(); 
} 

class MyClass2 : DancesWithWolves 
{ 
    public void DanceWithWolves() { /* ... */ } 
} 

class MyClass1 : DancesWithWolves 
{ 
    private readonly DancesWithWolves m_myClass2; 

    public MyClass1(DancesWithWolves myClass2) 
    { 
     m_myClass2 = myClass2; 
    } 

    public void DanceWithWolves() 
    { 
     m_myClass2.DanceWithWolves(); 
    } 
} 

class MyClass3 
{ 
    public void MyClass3Method(DancesWithWolves myClass1) 
    { 
     myClass1.DanceWithWolves(); 
    } 
} 

這不僅隱藏MyClass2從MyClass3但給你的機會,後來通過簡單地注入接口的另一個實現交換MyClass1的行爲。基斯在他的回答中已經提到了德米特定律,如果你想弄清楚爲什麼你應該使用接口並避免強有力的依賴關係,就像你使用「方式1」一樣,這也是值得一讀的。

注:這是不是一個「做總是這樣」 - 有可以是情況下,您實際上回報「MyClass2」的實例給客戶端。我的回答是基於你給出的示例代碼,因此假設這不是這種情況。 (見拉塞的評論,如果你現在正在混淆;))

1

這一切都與抽象有關,因爲我喜歡糟糕的比較,所以我會將它與汽車進行比較。

啓動汽車時,需要內燃機火:

public class Car 
{ 
    private IEngine _engine; 

    public Car(IEngine engine) 
    { 
     _engine = engine; 
    } 

    public void StartMoving() 
    { 
     if (_engine is CombustionEngine ce) 
     { 
      ce.FireSparkPlugs(); 
     } 
     else 
     { 
      // ... 
     } 
    } 
} 

現在考慮的選擇,在這裏你還車時的內臟給調用者(無論你做,通過一種方法或財產無所謂):

public class Car 
{ 
    private IEngine _engine; 

    public Car(IEngine engine) 
    { 
     _engine = engine; 
    } 

    public IEngine GetEngine() 
    { 
     return _engine; 
    } 
} 

現在呼叫者必須知道汽車有什麼樣的發動機讓它動,而他們不應該有,因爲他們正在處理的車輛的抽象水平離子:車輛。他們只是想讓車輛開始行駛,他們不想知道車輛是如何移動的。

現在你不能改變你進入汽車的發動機的種類,因爲那時呼叫者會中斷。另一方面,如果您希望調用者能夠檢查發動機,因爲這對汽車上的某些操作有意義,那麼可以肯定的是,您可以將其暴露。

+2

關注此評論嗎? – CodeCaster

+0

我沒有投票! –

+1

我也喜歡糟糕的比較:D +1有些降薪只是一個謎。 – Fildor

相關問題