C#-关于带参数的单例模式的思考(利用带参数的单例模式连接并查询数据库特定

时间:2022-01-29 03:51:44

首先,让我们看一下单例模式是怎样的。

    public sealed class Singleton
    {
        private static Singleton instance = null;
        private static readonly object padlock = new object();

        Singleton()
        {
        }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (padlock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

这是<<C# in Depth>>这本书中提供的标准代码。

实现单例模式的思路是:

  1. 定义一个密封类(sealed)以避免其它类继承此类(据书中所说此举虽然不是必要的,但可以帮助JIT进行更多优化)。
  2. 定义并初始化该类自身的静态实例(instance)为null,用该instance来检测控制在创建单例模式的类的程序中只有一个该类的实例。
  3. 定义并初始化一个只读(readonly)的用于锁(lock)的object对象以满足多线程环境。
  4. 创建一个只有get方法的该类的静态变量,用于创建该类的实例。
  5. 最后在该类的构造函数中写入相关代码。

可以看到整个过程中并未传入参数。

考虑以下问题:

如果我用单例模式连接并查询数据库单个表的所有信息,但数据库中有很多表,我想往单例模式中传入参数怎么办?

看以下代码:

public sealed class Database
    {
        private static Database _instance = null;
        private static readonly object _Object = new object();
        private string conString = "connection string";
        private Database(string tableName, DataTable dt)
        {
            using (SqlConnection Conn = new SqlConnection(conString))
            {
                Conn.Open();
                string sql = "select * from "   tableName;
                using (SqlCommand cmd = new SqlCommand(sql))
                {
                    using (SqlDataAdapter da = new SqlDataAdapter())
                    {
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = Conn;
                        da.SelectCommand = cmd;
                        da.Fill(dt);
                    }
                }
            }
        }
        public static Database GetInstance(string tableName, DataTable dt)
        {
            if (_instance == null)
            {
                lock (_Object)
                {
                    if (_instance == null)
                    {
                        _instance = new Database(tableName, dt);
                    }
                }
            }
            return _instance;
        }
    }
            DataTable dt = new DataTable();
            Database.GetInstance("MyTable",dt);
            Database.GetInstance("MyTable2", dt);
            dataGridView1.DataSource = dt;

由于单例模式,DataGridView中将只显示‘MyTable’的信息。

问题虽然得到解决,但单例模式通常提供对该实例的简单访问,是否使用工厂模式会有更合适呢?

待续...