2017-08-16 12 views
1

メソッド呼び出しC#で内部バインドされたクラスメソッドにアクセスするより良い方法は何ですか?

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(); 
    } 
} 
経由

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(); 
    } 
} 
  • パブリックプロパティを使用して

    1. 、内部バウンドクラスにアクセスするためのより良いと最適化された方法は何ですか

      MyClass2MethodMyClass2、クラスMyClass3でメソッドを呼び出すベストプラクティスは何ですか? MyClass2はMyClass3で参照されません。

      ウェイ1またはウェイ2

  • +0

    "Way 2"の方向にインターフェイスとgiongを使用することをお勧めしますが、具体的なクラスではなくインターフェイスを使用してください。 MyClass3はMyClass1の内部でどのように処理されているか気にしません。気にする必要はありません(「Way 1」の場合)。 – Fildor

    +0

    ウェイ2がウェイ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(); 
        } 
    } 
    

    これだけではなくMyClass3からMyClass2を隠しますが、あとで簡単にインタフェースの別の実装を注入することによって、MyClass1の振る舞いを交換する機会を与えてくれます。

    Keithはすでに彼の答えでLawのDemeterについて言及しています。なぜなら、あなたが "way 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

    関連する問題