[散分帖] 简单工厂与抽象工厂

coln_cheng 2008-06-18 09:27:14
建群散分:1187769 .net技术交流

1.抽象工厂模式是对普通工厂模式的扩充,适合于以下情况:
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

2.抽象工厂模式说明:
假设一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构。那么为了将消费这些产品对象的责任和创建这些产品对象的责任分开,可以引进抽象工厂模式。这样的话,消费产品的客户不需要直接参与产品的创建工作,而只需要向一个公用的工厂接口请求所需要的产品。

(1)抽象工厂模式设计到以下的角色:
抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用接口或抽象类实现。
具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。通常使用具体的类实现。
抽象产品角色:担任这个角色的类是抽象工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用接口或抽象类实现这一角色。
具体产品角色:抽象工厂模式所创建的任何产品对象都是某一具体产品类的实例。这是客户端最终需要的东西。通常使用具体类实现这个角色。
(2)实例代码
//抽象工厂接口
public interface Creator
{
ProductA factoryA();
ProductB factoryB();
}
//具体工厂1
public class ConcreteCreator1:Creator
{
public ProductA factoryA()
{
return new ProductA1();
}
public ProductB factoryB()
{
return new ProductB1();
}
}
//具体工厂2
public class ConcreteCreator2:Creator
{
public ProductA factoryA()
{
return new ProductA2();
}
public ProductB factoryB()
{
return new ProductB2();
}
}

//抽象产品接口
public interface ProductA
{
}
//具体产品1
public class ProductA1:ProductA
{
public ProductA1()
{
}
}
//具体产品2
public class ProductA2:ProductA
{
public ProductA2()
{
}
}

public interface ProductB
{
}

public class ProductB1:ProductB
{
public ProductB1()
{
}
}

public class ProductB2:ProductB
{
public ProductB2()
{
}
}
-----------------------------------------------------------------------------------------------------------------------------------------
简单工厂又称静态工厂,具体使用如下:

首先定义一个接口,具体名为Idatabase,在这个接口中,定义好数据库操作的方法名和参数,以及返回值,本案例中我定义如下方法:
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();
}
}
OK!以上是一个简单工厂模式实例...
...全文
594 61 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
61 条回复
切换为时间正序
请发表友善的回复…
发表回复
vane2009512 2009-05-25
  • 打赏
  • 举报
回复
我顶
qinyeya 2008-06-22
  • 打赏
  • 举报
回复
学习了 好贴一定要顶
meceky 2008-06-20
  • 打赏
  • 举报
回复
学习了 。。慢慢理解!
  • 打赏
  • 举报
回复
接着了,up,连接带顶
wingtech5323 2008-06-19
  • 打赏
  • 举报
回复
子慎怕,路过坟地,灵机一动,对坟墓说:爸爸,我回来了,开门啊。男子大惧,哇哇大叫奔逃。女子心安,正要离开,忽然从坟墓中传来阴森森的声音:闺女,你又忘了带钥匙啊。女子惊骇,也哇哇奔逃。这时从坟墓里钻出个盗墓的说:靠,耽误我工作,吓死你们! 盗墓的话音刚落,发现旁边有个老头正拿著凿子刻墓碑,好奇,问之,老头愤怒地说,NND,他们把我的名字刻错了……盗墓的大惧,哇哇叫著奔逃。老头冷笑一声:“靠,敢和我抢生意,还嫩点儿……
banAlist 2008-06-19
  • 打赏
  • 举报
回复
不错,谢谢楼主,
学习,
oxlshmily 2008-06-18
  • 打赏
  • 举报
回复
这个我懂,呵呵
接分...
diablososi 2008-06-18
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 designonline 的回复:]
~~~~~~~~~~~~~~~~接分
[/Quote]
nnoovvee 2008-06-18
  • 打赏
  • 举报
回复
up
学习+收藏!!!!!!!!!!!
designonline 2008-06-18
  • 打赏
  • 举报
回复
~~~~~~~~~~~~~~~~接分
guanghua100 2008-06-18
  • 打赏
  • 举报
回复
~~~~~~~~~接分
  • 打赏
  • 举报
回复
GOF的模式已经过去很多年了,回首来看,它的一大问题就是把单个方法、属性的扩展,本来是个简单的事件方法、属性注入的东西,硬设计成一个单个的领域类型。结果,领域类型泛滥了,含糊了。本来,类型是用来封装领域知识的。如果把每个可能扩展的方法、属性都设计为策略接口、工厂接口,概念肯定泛滥成灾。
cheng_feng001 2008-06-18
  • 打赏
  • 举报
回复
标记下,学习
回复内容太短了!好短算短嘛
zhangxiaolei422 2008-06-18
  • 打赏
  • 举报
回复
接分,讲的还可以............
xuStanly 2008-06-18
  • 打赏
  • 举报
回复
占位学习。


回复内容太短了!
回复内容太短了!
wzy_love_sly 2008-06-18
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 ShadowInWind 的回复:]
顶lz一帖,顺便接个分~
[/Quote]
大自然D使者 2008-06-18
  • 打赏
  • 举报
回复
谢谢楼主
收藏了
学习学习
prewin 2008-06-18
  • 打赏
  • 举报
回复
好东西,顶起!好东西,顶起!好东西,顶起!好东西,顶起!好东西,顶起!
wuyi8808 2008-06-18
  • 打赏
  • 举报
回复
jf
j147933783 2008-06-18
  • 打赏
  • 举报
回复
知道了,
真是好东西啊.
支持
加载更多回复(41)

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧