模板方法模式:(类库中大量使用,例如IDbConnection接口----->DbConnection抽象类------>派生的SqlConnection和派生的OleDbConnection就是使用了这种方法)
1。接口,到能做的定义进来。(一种规范).
2.把共同的部分进去分离出来,放到一个抽象的父类去实现.
3.子类中实现(不同的操作),父类中一般标记为abstract 或者override的虚方法
下面上具体的操作例子,定义一个从数据库中取数据和写数据。
//定义接口
interface ISettingprovider
{
string this[string name] { get; set; }//索引器
string[] Name{get;}//遍历配置项
bool ExistName(string name);//是否存大配置项
}
2.定义实现接口的抽象类
public abstract class BaseSettingProvider:ISettingprovider
{
protected abstract IDbConnection CreateConnection();
#region ISettingprovider 成员
public string this[string name]
{
get
{
using (IDbConnection conn = CreateConnection())
{
conn.Open();
using(IDbCommand cmd=conn.CreateCommand)
{
cmd.CommandText = "select * from T_Setting where [Name]='"+name+"'";
IDataReader dr=cmd.ExecuteReader();
while(dr.Read()==false)
{
throw new Execption("没有找到值");
}
return dr.GetString(dr.GetOrdinal("Value"));
}
}
}
set
{
if (ExistName(name))//判断配置项是否存在1,存在
{
using (IDbConnection conn = CreateConnection())
{
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "update T_Setting set [Value]='" + value + "' where Name='" + name + "'";
cmd.ExecuteNonQuery();
}
}
}
else
{
//没有此配置项,则插入新数据
using (IDbConnection conn = CreateConnection())
{
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "insert into T_Setting(Name,[Value])values('"+name+"','"+value+"')";
cmd.ExecuteNonQuery();
}
}
}
}
}
/// <summary>
/// 遍历所有配置项
/// </summary>
public string[] Name
{
get
{
List<string> list = new List<string>();
using (IDbConnection conn = CreateConnection())
{
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Setting";
IDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
list.Add(dr.GetString(dr.GetOrdinal("Name")));
}
return list.ToArray();
}
}
}
}
/// <summary>
/// 判断配置项是否存在
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public bool ExistName(string name)
{
return Name.Contains(name);//查看遍历的配置项中是否有这项
}
#endregion
}
3.定义抽象类的派生子类
public class SqlSettingProvider:BaseSettingProvider
{
string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
protected override System.Data.IDbConnection CreateConnection()
{
return new SqlConnection(connstr);
}
}
4.使用
string provider = ConfigurationManager.ConnectionStrings["connstr"].ProviderName;
ISettingprovider sp = null;
if (provider == "sql")
{
sp = new SqlSettingProvider();
}
else if (provider == "Access")
{
}
else
{
throw new Exception("没有这个数据类型");
}
Console.WriteLine(sp.ExistName("用户名"));
foreach(string name in sp.Name)
{
Console.WriteLine(name);
}
Console.ReadKey();
}
从中可以看到,相同的执行操作都放在一个抽象类中去实现了,不同的操作,都交给子类去处理.