2012-01-22 14 views
5

Estoy agregando y reemplazando dinámicamente controles en un panel de winform en tiempo de ejecución¿Cómo se puede reemplazar la herencia con interfaces en el patrón de fábrica?

Aunque todos los trabajos me han indicado que implemente interfaces en lugar de heredar desde un baseUserControl.

estoy a favor de ella, pero yo no veo cómo puedo conseguir el mismo resultado utilizando interfaces

¿Cómo puedo codificar mi fábrica?

¿Cómo se puede mejorar esto y usar interfaces en su lugar?

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

parece una pregunta para http://codereview.stackexchange.com/ – GolfWolf

+3

¿Por qué? ¿Cuál sería la ventaja de usar interfaces sobre la clase base? – Oded

+0

Estos no son exclusivos. Su IUserControl puede declarar DoSomething(), y puede implementar BaseControl como implementación de IUserControl (y devolver un IUserControl de fábrica). – Joe

Respuesta

7

Así es como puede hacerlo:

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

Puede conservar BaseUserControl si tiene alguna funcionalidad que es común a UserControlA y UserControlB; de lo contrario, elimínelo y haga que los dos últimos se derivan directamente del UserControl.

debe definir todos los miembros que pueda necesitar acceder desde sus clases derivadas dentro de su interfaz IControl. Esto incluye a los miembros que heredará del UserControl. Sin embargo, no necesitará volver a implementar estos dentro de sus clases concretas.

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

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

Si es necesario agregar estos controles para una aplicación Windows Forms - por lo general como el argumento de una llamada Control.ControlCollection.Add método - que tendrá que obtener una instancia Control correspondiente a su control. Bajo la implementación actual, esto se puede lograr simplemente a través del casting; sin embargo, esto debe aislarse de los consumidores de su interfaz, en caso de que decida cambiar la implementación subyacente en el futuro. Por lo tanto, me gustaría utilizar:

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

En su código de cliente:

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

+1 para AsWindowsForms() visión – radarbob

Cuestiones relacionadas