如何用工厂模式中的接口替换继承

本文关键字:接口 替换 继承 何用 工厂 模式 | 更新日期: 2023-09-27 18:20:58

我在运行时中动态添加和替换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
    }
}

如何用工厂模式中的接口替换继承

以下是如何做到这一点:

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

如果您具有UserControlAUserControlB通用的任何功能,则可以保留BaseUserControl;否则,将其消除,使后两者直接从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);