如何正确对接现有的密封类
本文关键字:密封类 何正确 | 更新日期: 2023-09-27 18:25:22
在CodeReview上审阅了我的代码后,我一直在思考如何使我的代码更加抽象。
正如您在这里看到的,许多人建议我应该创建一个ICommand
和IConnection
接口,以使重构更容易。
在我的例子中,我将只使用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();
}
现在,我的问题是,MySqlConnection
就是sealed
;我不能扩展它,因此我不知道有什么选项可以使这个数据库类抽象。
问题是;有没有合适的方法来实现Database
的抽象?如果有,我将如何实现?
请注意这个问题与类是否为singleton无关(如我的CodeReview帖子中所示)。这个问题已经提出,与这个问题无关。
阅读关于代码审查的评论,我实际上认为它们意味着使用IDbConnection
和IDbCommand
,而不是自己滚动。所有ADO.NET提供程序都已经实现了这些。
但是,如果需要,可以从DbConnection
和IConnection
继承,并包装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
字段名称,那么您可以用接口定义的单个属性来包装它们。我的意思是,你是统治局面的人,而继承可能会在这一点上限制你。
无论如何,在开始实现某个东西之前,试着用接口描述所有东西,然后才实现类。