代码重复,相同功能不同类型

Code duplication, same functionality different types

我有这个适用于 Npgsql 的方法:

private DataTable GetTableN(string sql, string[] pars)
    {
        NpgsqlCommand zapytanie = new NpgsqlCommand(sql, connn, trann);
        NpgsqlDataAdapter da = new NpgsqlDataAdapter();
        DataSet ds = new DataSet();
        try
        {
            if (pars != null)
            {
                for (int i = 0; i < pars.Length; i++)
                {
                    zapytanie.Parameters.AddWithValue("@param" + i, pars[i]);
                }
            }
            connn.Open();
            da.SelectCommand = zapytanie;
            da.Fill(ds);
            return ds.Tables[0];
        }
        catch (NpgsqlException e)
        {
            throw (new SqlException(e.Message.ToString()));
        }
        finally
        {
            connn.Close();
            zapytanie.Dispose();
            da.Dispose();
            ds.Dispose();
        }
    }

现在我需要使用完全相同的方法,但改用 Odbc。我只需要进行这些更改

  1. NpgsqlCommand 到 ObdcCommand
  2. NpgsqlDataAdapter 到 OdbcDataAdapter
  3. NpgsqlException 到 OdbcException

如何合并它以避免代码重复并且只有一种方法?

您可以尝试更改方法的签名

private DataTable GetTableN(string sql, string[] pars, DbCommand zapytanie, DbDataAdapter da)
{   
    DataSet ds = new DataSet();
    try
    {
        if (pars != null)
        {
            for (int i = 0; i < pars.Length; i++)
            {
                zapytanie.Parameters.AddWithValue("@param" + i, pars[i]);
            }
        }
        connn.Open();
        da.SelectCommand = zapytanie;
        da.Fill(ds);
        return ds.Tables[0];
    }
    catch (DbException e)
    {
        throw (new SqlException(e.Message.ToString()));
    }
    finally
    {
        connn.Close();
        zapytanie.Dispose();
        da.Dispose();
        ds.Dispose();
    }
}

或者使用某种工厂

private DataTable GetTableN(string sql, string[] pars, MyFactory factory)
{
    DbCommand zapytanie = factory.CreateCommand(...);
    DbDataAdapter da = new factory.CreateAdapter(...);
    ...
}

或者您可以为此使用继承

public abstract class MyClass
{
    private DataTable GetTableN(string sql, string[] pars)
    {
        DbCommand zapytanie = CreateCommand();
        DbDataAdapter da = CreateAdapter();
        ...
    }

    protected abstract DbCommand CreateCommand();
    protected abstract DbDataAdapter CreateAdapter();
}

public class OdbcClass : MyClass
{
    protected override DbCommand CreateCommand()
    {
        // create for odbc
    }

    protected override DbDataAdapter CreateAdapter()
    {
        // create for odbc
    }
}

public class PostgrClass : MyClass
{
    protected override DbCommand CreateCommand()
    {
        // create for postgr
    }

    protected override DbDataAdapter CreateAdapter()
    {
        // create for postgr
    }
}

我想工厂模式是可行的方法。谢谢。