2012-01-22 6 views
5

मैं गतिशील जोड़ने कर रहा हूँ और क्रमफैक्ट्री पैटर्न में इंटरफेस के साथ विरासत को कैसे बदला जा सकता है?

पर एक WinForm पैनल में नियंत्रण की जगह यहां तक ​​कि सभी कार्यों मैं नहीं बल्कि एक baseUserControl से इनहेरिट से इंटरफेस को लागू करने को कहा गया है, हालांकि।

मैं इसके लिए सभी हूँ, लेकिन मैं न देखते हैं कि कैसे मैं मैं इंटरफेस

मैं अपने फैक्टरी कोड होगा कैसे का उपयोग कर एक ही परिणाम प्राप्त कर सकते हैं?

यह कैसे सुधार किया जा सकता है और इसके बजाय इंटरफेस का उपयोग कैसे किया जा सकता है?

//Simplified noddy example 

//Client code 
var controlA = ControlFactory 
    .Create("UserControlA") as UserControlA; 

panel1.Controls.Add(ControlA); 

//Factory 
public class ControlFactory 
{ 
    public static BaseUserControl Create(string name) 
    { 
     switch (name) 
     { 
      case "UserControlA": 
       var userControlA = new UserControlA(); 

       return userControlA; 

      case "UserControlB": 
       var userControlB = new UserControlB(); 
       return userControlB; 
     } 
     return null; 
    } 
} 
    //BaseUserControl 
    public partial class BaseUserControl : UserControl 
    { 
     public BaseUserControl() 
     { 
      InitializeComponent(); 
     } 

     public virtual void DoSomething() 
     { 

     } 
    } 

    public partial class UserControlA : BaseUserControl 
    { 
     public UserControlA() 
     { 
      InitializeComponent(); 
     } 

     public override void DoSomething() 
     { 
      //Do something here 
     } 
    } 

public partial class UserControlB : BaseUserControl 
{ 
    public UserControlB() 
    { 
     InitializeComponent(); 
    } 

    public override void DoSomething() 
    { 
     //Do something here 
    } 
} 
+0

http://codereview.stackexchange.com/ – GolfWolf

+3

क्यों के लिए एक सवाल की तरह लग रहा है? बेस क्लास पर इंटरफेस का उपयोग करने का क्या फायदा होगा? – Oded

+0

ये अनन्य नहीं हैं। आपका IUserControl DoSomething() घोषित कर सकता है, और आप IUserControl को लागू करने के रूप में बेसकंट्रोल को कार्यान्वित कर सकते हैं (और कारखाने से IUserControl वापस कर सकते हैं)। – Joe

उत्तर

7

यहाँ कैसे आप यह कर सकते है:

using System; 
using System.Windows.Forms; 
using System.ComponentModel; 

//Interface 
public interface IControl : IComponent 
{ 
    void DoSomething(); 
} 

//Factory 
public class ControlFactory 
{ 
    public static IControl Create(string name) 
    { 
     switch (name) 
     { 
      case "UserControlA": 
       var userControlA = new UserControlA(); 

       return userControlA; 

      case "UserControlB": 
       var userControlB = new UserControlB(); 
       return userControlB; 
     } 
     return null; 
    } 
} 

//BaseUserControl 
public partial class BaseUserControl : UserControl, IControl 
{ 
    public BaseUserControl() 
    { 
     InitializeComponent(); 
    } 

    public virtual void DoSomething() 
    { 

    } 
} 

public partial class UserControlA : BaseUserControl, IControl 
{ 
    public UserControlA() 
    { 
     InitializeComponent(); 
    } 

    public override void DoSomething() 
    { 
     //Do something here 
    } 
} 

public partial class UserControlB : BaseUserControl, IControl 
{ 
    public UserControlB() 
    { 
     InitializeComponent(); 
    } 

    public override void DoSomething() 
    { 
     //Do something here 
    } 
} 

आप बनाए रख सकते हैं BaseUserControl अगर आप UserControlA और UserControlB के लिए आम है कि किसी भी कार्यक्षमता है; अन्यथा, इसे खत्म करें और बाद वाले दो को UserControl से सीधे प्राप्त करें।

उन सभी सदस्यों को परिभाषित करना चाहिए जिन्हें आपको अपने IControl इंटरफ़ेस में अपने व्युत्पन्न कक्षाओं से एक्सेस करने की आवश्यकता हो सकती है। इसमें UserControl से प्राप्त होने वाले किसी भी सदस्य शामिल हैं। हालांकि, आपको अपने ठोस वर्गों के भीतर इन्हें फिर से लागू करने की आवश्यकता नहीं होगी।

//Interface 
public interface IControl : IComponent 
{ 
    void DoSomething(); 

    // To be inherited from UserControl. 
    Size Size { get; set; } 
    bool Focus(); 
    event EventHandler FontChanged; 
} 

आप Windows के लिए इन नियंत्रणों को जोड़ने के लिए की जरूरत है आवेदन फॉर्म्स - आम तौर पर एक Control.ControlCollection.Add विधि कॉल करने के लिए तर्क के रूप में - आप एक Control उदाहरण अपने नियंत्रण करने के लिए इसी पाने के लिए की आवश्यकता होगी। वर्तमान कार्यान्वयन के तहत, यह केवल कास्टिंग के माध्यम से हासिल किया जा सकता है; हालांकि, यदि आप भविष्य में अंतर्निहित कार्यान्वयन को बदलने का निर्णय लेते हैं, तो इसे आपके इंटरफ़ेस के उपभोक्ताओं से इन्सुलेट करने की आवश्यकता है। इस प्रकार, मैं का प्रयोग करेंगे:

//Interface 
public interface IControl : IComponent 
{ 
    void DoSomething(); 

    Control AsWindowsForms(); 
} 

//BaseUserControl 
public partial class BaseUserControl : UserControl, IControl 
{ 
    public BaseUserControl() 
    { 
     InitializeComponent(); 
    } 

    public virtual void DoSomething() 
    { 

    } 

    public Control AsWindowsForms() 
    { 
     return this as Control; 
    } 
} 

अपने ग्राहक कोड में:

var controlA = ControlFactory.Create("UserControlA").AsWindowsForms(); 
var controlB = ControlFactory.Create("UserControlB").AsWindowsForms(); 
panel1.Controls.Add(controlA); 
panel1.Controls.Add(controlB); 
+0

+1 – radarbob

संबंधित मुद्दे