2012-01-22 9 views
5

Sto dinamicamente Aggiunta e sostituzione di controlli di un pannello WinForm in fase di esecuzioneIn che modo è possibile sostituire l'ereditarietà con le interfacce nel modello di fabbrica?

Anche se tutte le opere mi è stato detto di implementare interfacce piuttosto che eredita da un baseUserControl.

Io sono tutto per esso, ma io non vedo come posso io ottenere lo stesso risultato utilizzando interfacce

Come faccio a codificare la mia fabbrica?

Come può essere migliorato e utilizzare invece le interfacce?

//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

si presenta come una domanda per il http://codereview.stackexchange.com/ – GolfWolf

+3

Perché? Quale sarebbe il vantaggio di utilizzare le interfacce rispetto alla classe base? – Oded

+0

Questi non sono esclusivi. IUserControl può dichiarare DoSomething() ed è possibile implementare BaseControl come implementazione di IUserControl (e restituire un IUserControl dalla fabbrica). – Joe

risposta

7

Ecco come si può fare:

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 
    } 
} 

È possibile mantenere BaseUserControl se si dispone di alcuna funzionalità che è comune a UserControlA e UserControlB; altrimenti, eliminalo e fai in modo che gli ultimi due derivino direttamente da UserControl.

È definire tutti i membri che potrebbero essere necessari per accedere dalle classi derivate all'interno dell'interfaccia IControl. Questo include qualsiasi membro ereditato da UserControl. Tuttavia, non avrai bisogno di ri-implementare questi all'interno delle tue lezioni concrete.

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

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

Se avete bisogno di aggiungere questi controlli per un'applicazione Windows Form - in genere come argomento di una chiamata Control.ControlCollection.Add metodo - è necessario per ottenere un'istanza Control corrispondente al vostro controllo. Nell'attuale implementazione, ciò può essere ottenuto semplicemente attraverso il casting; tuttavia, questo deve essere isolato dai consumatori della tua interfaccia, nel caso in cui decidessi di cambiare l'implementazione sottostante in futuro. Così, vorrei utilizzare:

//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; 
    } 
} 

Nel codice client:

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

+1 per l'intuizione AsWindowsForms() – radarbob

Problemi correlati