繁体   English   中英

如何正确接口现有的密封类?

[英]How to correctly interface an existing sealed class?

在CodeReview上检查了我的代码之后,我陷入了一个问题,即如何使我的代码片段更加抽象。

如您在这里看到的,许多建议我应该创建一个ICommandIConnection接口,以使其易于重构。

在我的示例中,我将仅使用IConnection ,但整个过程对于ICommand也应有效。

我认为我必须创建一个这样的接口;

public interface IConnection
{
     //etc...
}

然后,为了使MySqlConnection能够从我的IConnection继承,我必须创建自己的MySqlConnection ,它会像这样继承;

public class MySqlConnection : MySql.Data.MySqlClient.MySqlConnection, IConnection
{
     //etc...
}

这意味着新MySqlConnection仍然有其方法和字段, 会继承IConnection 然后,我应该能够编写这样的Database类;

public abstract class Database
{
    protected IConnection con;
}

并像这样扩展它;

public class MySqlDatabase : Database
{
    private override IConnection con = new MySqlConnection();
}

现在,我的问题是, MySqlConnectionsealed 我无法扩展它,因此我不知道使该数据库类抽象的任何选择。

问题是; 有没有适当的方法来实现Database的抽象?如果是,我该怎么做?

请注意 ,此问题与类为单例无关(如我的CodeReview帖子中所示)。 该问题已经发布,与该问题无关。

阅读有关代码审查的评论,我实际上认为它们的意思是使用IDbConnectionIDbCommand而不是自己动手。 所有ADO.NET提供程序都已经实现了这些功能。

但是,如果您愿意,可以继承DbConnectionIConnection包装 MySqlConnection 您必须实现所有DbConnection方法并将它们中继到包装的连接:

public sealed class MyMySqlConnection : DbConnection, IConnection
{
    public MyMySqlConnection(MySqlConnection underlyingConnection)
    {
        UnderlyingConnection = underlyingConnection;
    }

    public MySqlConnection UnderlyingConnection
    {
        get;
        private set;
    }

    public override void Open()
    {
        UnderlyingConnection.Open();
    }

    // ...

如何实现装饰器模式:

interface IConnection
{
    string ConnectionString {get; set;} // Define your interface explicitly
}

然后,您可以创建一个这样的类:

class MySqlDbConnection : IConnection
{
    private MySql.Data.MySqlClient.MySqlConnection connection;

    public MySqlConnection(MySql.Data.MySqlClient.MySqlConnection connection)
    {
        // Check for null
        this.connection = connection;
    }

    #region Implementation of IConnection
    public ConnectionString
    {
        get
        {
            return connection.ConnectionString; // Not sure if this is the right name of property
        }
        set
        {
            connection.ConnectionString = value;
        }
    }
    #endregion
}

所以你会这样实现:

1)您可以显式公开您真正需要的Connection类的那些字段

2)您仍然可以在具体的Database类的初始化阶段进行初始配置

3),您的代码变得更加抽象

4)什么是非常方便的-如果不同数据库的连接(例如mysql / sqlite等)将具有不同的connectionString字段名称-那么您可以使用接口定义的单个属性包装它们。 我的意思是-您是掌管局势的人,继承在这一点上可能会限制您。

无论如何,在开始实现某些东西之前,请尝试使用接口描述所有内容,然后才实现类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM