public interface IDatabase
{
bool Connect(string ConnectString);
bool Open();
bool Command(string SQL);
void Close();
}
重要提醒:“接口一生唯谨慎,定义大事不糊涂”,编写接口时一定要考虑周全,并对参数、返回值进行反复推敲,为什么?因为所有的实现类都是要根据该接口的规范进行代码具体编写,也即接口的定义是公用的,一旦改动了接口,后果就是所有的实现类也都必须相应调整。
然后就是编写具体的实现类了,客户要求多少不同类型的数据库,你就定义多少个Idatabase的实现类,虽然工作量大了点,可当你看到客户满意的笑容时,你心里也就会有一种由衷的幸福感,好了,SqlServer实现类代码如下:
public class SqlServer : IDatabase
{
SqlConnection conn;
SqlCommand command;
public bool Connect(string ConnectString)
{
try
{
conn = new SqlConnection(ConnectString);
return true;
}
catch(SqlException)
{
return false;
}
}
public bool Open()
{
try
{
conn.Open();
return true;
}
catch(SqlException)
{
return false;
}
}
public bool Command(string SQL)
{
try
{
command = new SqlCommand(SQL,conn);
command.ExecuteNonQuery();
return true;
}
catch(SqlException)
{
return false;
}
}
public void Close()
{
conn.Close();
conn.Dispose();
}
}
呵呵,有点长,咬着牙读完,心里明白了就会很舒服的,如果你现在有这种感觉了,好,再接再厉,再为Oracle实现类编写具体代码吧,依葫芦画瓢,大家有空就画一下吧,我就画个雏形了:
public class Oracle : IDatabase
{
public Oracle()
{
}
public bool Connect(string ConnectString)
{
return true;
}
public bool Open()
{
return true;
}
public bool Command(string SQL)
{
return true;
}
public void Close()
{
}
}
嗯,不错,你有多少种数据库就编写不同的实现类代码吧,这里就不赘述了,接下来呢?聪明的读者一定会想到这个问题:这个接口和这么多的实现类怎么用啊?我们再定义一个称之为工厂的类,由它来决定选用哪种数据库为进行操作,这个类比较简单:
public class Factory
{
public static IDatabase SelectDatabase(string DatabaseType)
{
switch(DatabaseType)
{
case "SqlServer":
return new SqlServer();
case "Oracle":
return new Oracle();
default:
return new SqlServer();
}
}
}
看明白了吗?好了,我们该让尊敬的、永远高贵的客户出场了,只有他,唯有他才有决定用哪种数据库的最高权限,你看,他这样用:
public class Client
{
public static void Main()
{
//Get the database information from Web.Config.
string DBType = ConfigurationSettings.AppSettings["DBType"];
string DBConnectString = ConfigurationSettings.AppSettings["DBConn"];
IDatabase DB = Factory.SelectDatabase(DBType);
//Connect the selected database.
if(DB.Connect(DBConnectString)==false)
{
Console.WriteLine("The database {0} can@#t be connected.",DBType);
return;
}
//Open database.
if(DB.Open()==false)
{
Console.WriteLine("The database {0} can@#t be opened, the connect string is {1}.",DBType,DBConnectString);
return;
}
//Execute SQL Command.
string SQL = "update Order set price = price * 0.07 where productID = @#002@#";
if(DB.Command(SQL))
{
//Do something...
}
else
{
Console.WriteLine("The Operator is not success. SQL statament is {0}",SQL);
DB.Close();
return;
}
DB.Close();
}
}
好了,工程峻工了,你们明白了没有?
思考题:简单工厂的应用场合和局限性?
作业题:假如要开发一个多媒体播放器,既能用Window MediaPlayer播放,又能用RealPlayer播放,还能用QuickTime播放,具体用什么播放器,由客户选择,请你画出UML图并写出代码。