簡體   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