简单工厂 抽象工厂模式,工厂方法模式和抽象工厂模式的区别

简单工厂模式,工厂方法模式和抽象工厂模式的异同
简单工厂模式,工厂方法模式和抽象工厂模式的异同
简单工厂模式,工厂方法模式和抽象工厂模式都是属于创建型设计模式,这三种创建型模式都不需要知道具体类。我们掌握一种思想,就是在创建一个对象时,需要把容易发生变化的地方给封装起来,来控制变化(哪里变化,封装哪里),以适应客户的变动,项目的扩展。用这三种设计模式都可以实现,那究竟这三种设计模式有什么异同呢?下面根据这三者之间的特点,优点,缺点,适用范围进行比较。
简单工厂模式:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式。它的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
工厂方法模式:工厂方法是粒度很小的设计模式,因为模式的表现只是一个抽象的方法。提前定义用于创建对象的接口,让子类决定实例化具体的某一个类,即在工厂和产品中间增加接口,工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例去实现。工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次实现更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式是对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
抽象工厂模式:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,一个抽象工厂类,可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。
简单工厂模式:工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。简单工厂模式通过这种做法实现了对责任的分割。简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。通过它,外界可以从直接创建具体产品对象的尴尬局面中摆脱出来。外界与具体类隔离开来,偶合性低。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
&&&&&&&&&&&&&&&&&&&&&
工厂方法模式:工厂方法模式是为了克服简单工厂模式的缺点(主要是为了满足OCP)而设计出来的。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。工厂方法模式完全满足OCP,即它有非常良好的扩展性。
&&&&&&&&&&&&&&&&&&&&&
抽象工厂模式:抽象工厂模式主要在于应对“新系列”的需求变化。分离了具体的类,抽象工厂模式帮助你控制一个应用创建的对象的类,因为一个工厂封装创建产品对象的责任和过程。它将客户和类的实现分离,客户通过他们的抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。它使得易于交换产品系列。一个具体工厂类在一个应用中仅出现一次——即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。它有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。抽象工厂模式有助于这样的团队的分工,降低了模块间的耦合性,提高了团队开发效率。
&&&&&&&&&&&&&&&&&&&&&
简单工厂模式:当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。
&&&&&&&&&&&&&&&&&&&&&
工厂方法模式:不易于维护,假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。
&&&&&&&&&&&&&&&&&&&&&
抽象工厂模式:抽象工厂模式在于难于应付“新对象”的需求变动。难以支持新种类的产品。难以扩展抽象工厂以生产新种类的产品。这是因为抽象工厂几乎确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂类及其所有子类的改变。
&&&&& &&&&&&&&&&&&&&&&
四.适用范围
简单工厂模式:工厂类负责创建的对象比较少,客户只知道传入了工厂类的参数,对于始何创建对象(逻辑)不关心。
&&&&&&&&&&&&&&&&&&&&&
工厂方法模式:当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法。
&&&&&&&&&&&&&&&&&&&&&
抽象工厂模式:一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统有多于一个的产品族,而系统只消费其中某一产品族。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
&&&&&&&&&&&&&&&&&&&&&
其实,无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定。
发表评论:
TA的最新馆藏[转]&<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&luozhonglan
阅读(10741)
1. 简单工厂模式
如何理解简单工厂,工厂方法, 抽象工厂三种设计模式?
简单工厂的生活场景,卖早点的小摊贩,他给你提供包子,馒头,地沟油烙的煎饼等,小贩是一个工厂,它生产包子,馒头,地沟油烙的煎饼。该场景对应的UML图如下所示:
图1:简单工厂模式UML图
简单工厂模式的参与者:
工厂(Factory)角色:接受客户端的请求,通过请求负责创建相应的产品对象。
抽象产品(Abstract Product)角色:
是工厂模式所创建对象的父类或是共同拥有的接口。可是抽象类或接口。
具体产品(ConcreteProduct)对象:工厂模式所创建的对象都是这个角色的实例。
简单工厂模式的演变:
1.)当系统中只有唯一的产品时,可以省略抽象产品,如图1所示。这样,工厂角色与具体产品可以合并。
简单工厂模式的优缺点:
1.)工厂类含有必要的创建何种产品的逻辑,这样客户端只需要请求需要的产品,而不需要理会产品的实现细节。
2.)工厂类只有一个,它集中了所有产品创建的逻辑,它将是整个系统的瓶颈,同时造成系统难以拓展。
3.)简单工厂模式通常使用静态工厂方法,这使得工厂类无法由子类继承,这使得工厂角色无法形成基于继承的等级结构。
2.&工厂方法模式
工厂方法使用OOP的多态性,将工厂和产品都抽象出一个基类,在基类中定义统一的接口,然后在具体的工厂中创建具体的产品。工厂方法的生活场景,联合利华要生产“夏士莲”和“清扬”两款洗发水,它会建一个生产“夏士莲”的工厂和一个生产“清扬”的工厂。
图2:工厂方法的UML图
工厂方法模式中的参与者:
抽象工厂角色:与应用程序无关,任何在模式中创建对象的工厂必须实现这个接口。
具体工厂角色:实现了抽象工厂接口的具体类,含有与引用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。
抽象产品角色:工厂方法所创建产品对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
具体产品角色:这个角色实现了抽象产品角色所声名的接口。工厂方法所创建的每个具体产品对象都是某个具体产品角色的实例。
工厂方法的优缺点:
1.)降低了工厂类的内聚,满足了类之间的层次关系,又很好的符合了面向对象设计中的单一职责原则,这样有利于程序的拓展,如图三所示:
图3:工厂方法的拓展UML图
总结:把“共性”提取出来,根据各自的“个性”建立各自的继承共性的实现
3. 抽象工厂设计模式
所谓抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象,以创建Unix控件和Windows控件为例说明,我们需要一个抽象工厂下面有两个子工厂,一个叫做UnixFactory,用于生产Unix族控件,一个叫做WinFactory,用于生产Win族控件。抽象工厂与工厂方法的区别是,工厂方法中的具体工厂一般只生产一个或几个控件对象,而抽象工厂中的具体工厂生产的是一族控件对象。如图4所示。
图4:抽象工厂设计模式UML图
抽象工厂中的参与者:
担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
抽象工厂的使用场景:
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。 这个系统有多于一个的产品族,而系统只消费其中某一产品族。 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
抽象工厂模式与工厂方法模式的区别
工厂方法模式:每个抽象产品派生多个具体产品类,每个抽象工厂类派生多个具体工厂类,每个具体工厂类负责一个具体产品的实例创建;&
抽象工厂模式:每个抽象产品派生多个具体产品类,每个抽象工厂派生多个具体工厂类,每个具体工厂负责多个(一系列)具体产品的实例创建。&
//在UIKit框架下,我们用工厂方法和抽象工厂两种设计模式分别实现了两份Demo, 不理解两种设计模式该如何实现的朋友可以到这里下载: &刷不出来,以后补上!
参考文章:
简单工厂:&
工厂方法:
抽象工厂:
阅读排行榜C#设计模式(4)——抽象工厂模式 - 文章 - 伯乐在线
& C#设计模式(4)——抽象工厂模式
在上一专题中介绍了,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,这是本专题所要介绍的内容。
二、抽象工厂详细介绍
这里首先以一个生活中抽象工厂的例子来实现一个抽象工厂,然后再给出抽象工厂的定义和UML图来帮助大家更好地掌握抽象工厂模式,同时大家在理解的时候,可以对照抽象工厂生活中例子的实现和它的定义来加深抽象工厂的UML图理解。
2.1 抽象工厂的具体实现
下面就以生活中 “绝味” 连锁店的例子来实现一个抽象工厂模式。例如,绝味鸭脖想在江西南昌和上海开分店,但是由于当地人的口味不一样,在南昌的所有绝味的东西会做的辣一点,而上海不喜欢吃辣的,所以上海的所有绝味的东西都不会做的像南昌的那样辣,然而这点不同导致南昌绝味工厂和上海的绝味工厂生成所有绝味的产品都不同,也就是某个具体工厂需要负责一系列产品(指的是绝味所有食物)的创建工作,下面就具体看看如何使用抽象工厂模式来实现这种情况。
/// &summary&
/// 下面以绝味鸭脖连锁店为例子演示下抽象工厂模式
/// 因为每个地方的喜欢的口味不一样,有些地方喜欢辣点的,有些地方喜欢吃不辣点
/// 客户端调用
/// &/summary&
class Client
static void Main(string[] args)
// 南昌工厂制作南昌的鸭脖和鸭架
AbstractFactory nanChangFactory = new NanChangFactory();
YaBo nanChangYabo = nanChangFactory.CreateYaBo();
nanChangYabo.Print();
YaJia nanChangYajia= nanChangFactory.CreateYaJia();
nanChangYajia.Print();
// 上海工厂制作上海的鸭脖和鸭架
AbstractFactory shangHaiFactory = new ShangHaiFactory();
shangHaiFactory.CreateYaBo().Print();
shangHaiFactory.CreateYaJia().Print();
Console.Read();
/// &summary&
/// 抽象工厂类,提供创建两个不同地方的鸭架和鸭脖的接口
/// &/summary&
public abstract class AbstractFactory
// 抽象工厂提供创建一系列产品的接口,这里作为例子,只给出了绝味中鸭脖和鸭架的创建接口
public abstract YaBo CreateYaBo();
public abstract YaJia CreateYaJia();
/// &summary&
/// 南昌绝味工厂负责制作南昌的鸭脖和鸭架
/// &/summary&
public class NanChangFactory : AbstractFactory
// 制作南昌鸭脖
public override YaBo CreateYaBo()
return new NanChangYaBo();
// 制作南昌鸭架
public override YaJia CreateYaJia()
return new NanChangYaJia();
/// &summary&
/// 上海绝味工厂负责制作上海的鸭脖和鸭架
/// &/summary&
public class ShangHaiFactory : AbstractFactory
// 制作上海鸭脖
public override YaBo CreateYaBo()
return new ShangHaiYaBo();
// 制作上海鸭架
public override YaJia CreateYaJia()
return new ShangHaiYaJia();
/// &summary&
/// 鸭脖抽象类,供每个地方的鸭脖类继承
/// &/summary&
public abstract class YaBo
/// &summary&
/// 打印方法,用于输出信息
/// &/summary&
public abstract void Print();
/// &summary&
/// 鸭架抽象类,供每个地方的鸭架类继承
/// &/summary&
public abstract class YaJia
/// &summary&
/// 打印方法,用于输出信息
/// &/summary&
public abstract void Print();
/// &summary&
/// 南昌的鸭脖类,因为江西人喜欢吃辣的,所以南昌的鸭脖稍微会比上海做的辣
/// &/summary&
public class NanChangYaBo : YaBo
public override void Print()
Console.WriteLine("南昌的鸭脖");
/// &summary&
/// 上海的鸭脖没有南昌的鸭脖做的辣
/// &/summary&
public class ShangHaiYaBo : YaBo
public override void Print()
Console.WriteLine("上海的鸭脖");
/// &summary&
/// 南昌的鸭架
/// &/summary&
public class NanChangYaJia : YaJia
public override void Print()
Console.WriteLine("南昌的鸭架子");
/// &summary&
/// 上海的鸭架
/// &/summary&
public class ShangHaiYaJia : YaJia
public override void Print()
Console.WriteLine("上海的鸭架子");
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
/// &summary&&&&&/// 下面以绝味鸭脖连锁店为例子演示下抽象工厂模式&&&&/// 因为每个地方的喜欢的口味不一样,有些地方喜欢辣点的,有些地方喜欢吃不辣点&&&&/// 客户端调用&&&&/// &/summary&&&&&class Client&&&&{&&&&&&&&static void Main(string[] args)&&&&&&&&{&&&&&&&&&&&&// 南昌工厂制作南昌的鸭脖和鸭架&&&&&&&&&&&&AbstractFactory nanChangFactory = new NanChangFactory();&&&&&&&&&&&&YaBo nanChangYabo = nanChangFactory.CreateYaBo();&&&&&&&&&&&&nanChangYabo.Print();&&&&&&&&&&&&YaJia nanChangYajia= nanChangFactory.CreateYaJia();&&&&&&&&&&&&nanChangYajia.Print();&&&&&&&&&&&&&// 上海工厂制作上海的鸭脖和鸭架&&&&&&&&&&&&AbstractFactory shangHaiFactory = new ShangHaiFactory();&&&&&&&&&&&&shangHaiFactory.CreateYaBo().Print();&&&&&&&&&&&&shangHaiFactory.CreateYaJia().Print();&&&&&&&&&&&&&Console.Read();&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 抽象工厂类,提供创建两个不同地方的鸭架和鸭脖的接口&&&&/// &/summary&&&&&public abstract class AbstractFactory&&&&{&&&&&&&&// 抽象工厂提供创建一系列产品的接口,这里作为例子,只给出了绝味中鸭脖和鸭架的创建接口&&&&&&&&public abstract YaBo CreateYaBo();&&&&&&&&public abstract YaJia CreateYaJia();&&&&}&&&&&/// &summary&&&&&/// 南昌绝味工厂负责制作南昌的鸭脖和鸭架&&&&/// &/summary&&&&&public class NanChangFactory : AbstractFactory&&&&{&&&&&&&&// 制作南昌鸭脖&&&&&&&&public override YaBo CreateYaBo()&&&&&&&&{&&&&&&&&&&&&return new NanChangYaBo();&&&&&&&&}&&&&&&&&// 制作南昌鸭架&&&&&&&&public override YaJia CreateYaJia()&&&&&&&&{&&&&&&&&&&&&return new NanChangYaJia();&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 上海绝味工厂负责制作上海的鸭脖和鸭架&&&&/// &/summary&&&&&public class ShangHaiFactory : AbstractFactory&&&&{&&&&&&&&// 制作上海鸭脖&&&&&&&&public override YaBo CreateYaBo()&&&&&&&&{&&&&&&&&&&&&return new ShangHaiYaBo();&&&&&&&&}&&&&&&&&// 制作上海鸭架&&&&&&&&public override YaJia CreateYaJia()&&&&&&&&{&&&&&&&&&&&&return new ShangHaiYaJia();&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 鸭脖抽象类,供每个地方的鸭脖类继承&&&&/// &/summary&&&&&public abstract class YaBo&&&&{&&&&&&&&/// &summary&&&&&&&&&/// 打印方法,用于输出信息&&&&&&&&/// &/summary&&&&&&&&&public abstract void Print();&&&&}&&&&&/// &summary&&&&&/// 鸭架抽象类,供每个地方的鸭架类继承&&&&/// &/summary&&&&&public abstract class YaJia&&&&{&&&&&&&&/// &summary&&&&&&&&&/// 打印方法,用于输出信息&&&&&&&&/// &/summary&&&&&&&&&public abstract void Print();&&&&}&&&&&/// &summary&&&&&/// 南昌的鸭脖类,因为江西人喜欢吃辣的,所以南昌的鸭脖稍微会比上海做的辣&&&&/// &/summary&&&&&public class NanChangYaBo : YaBo&&&&{&&&&&&&&public override void Print()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("南昌的鸭脖");&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 上海的鸭脖没有南昌的鸭脖做的辣&&&&/// &/summary&&&&&public class ShangHaiYaBo : YaBo&&&&{&&&&&&&&public override void Print()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("上海的鸭脖");&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 南昌的鸭架&&&&/// &/summary&&&&&public class NanChangYaJia : YaJia&&&&{&&&&&&&&public override void Print()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("南昌的鸭架子");&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 上海的鸭架&&&&/// &/summary&&&&&public class ShangHaiYaJia : YaJia&&&&{&&&&&&&&public override void Print()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("上海的鸭架子");&&&&&&&&}&&&&}
2.2 抽象工厂模式的定义和类图
上面代码中都有详细的注释,这里就不再解释上面的代码了,下面就具体看看抽象工厂模式的定义吧(理解定义可以参考上面的实现来加深理解):
抽象工厂模式:提供一个创建产品的接口来负责创建相关或依赖的对象,而不具体明确指定具体类
抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么。这样客户就可以从具体产品中被解耦。下面通过抽象工模式的类图来了解各个类中之间的关系:
2.3 抽象工厂应对需求变更
看完上面抽象工厂的实现之后,如果 “绝味”公司又想在湖南开一家分店怎么办呢? 因为湖南人喜欢吃麻辣的,下面就具体看看应用了抽象工厂模式的系统是如何应对这种需求的。
/// &summary&
/// 如果绝味又想开一家湖南的分店时,因为湖南喜欢吃麻的
/// 所以这是有需要有一家湖南的工厂专门制作
/// &/summary&
public class HuNanFactory : AbstractFactory
// 制作湖南鸭脖
public override YaBo CreateYaBo()
return new HuNanYaBo();
// 制作湖南鸭架
public override YaJia CreateYaJia()
return new HuNanYajia();
/// &summary&
/// 湖南的鸭脖
/// &/summary&
public class HuNanYaBo : YaBo
public override void Print()
Console.WriteLine("湖南的鸭脖");
/// &summary&
/// 湖南的鸭架
/// &/summary&
public class HuNanYajia : YaJia
public override void Print()
Console.WriteLine("湖南的鸭架子");
12345678910111213141516171819202122232425262728293031323334353637383940
/// &summary&&&&&/// 如果绝味又想开一家湖南的分店时,因为湖南喜欢吃麻的&&&&/// 所以这是有需要有一家湖南的工厂专门制作&&&&/// &/summary&&&&&public class HuNanFactory : AbstractFactory&&&&{&&&&&&&&// 制作湖南鸭脖&&&&&&&&public override YaBo CreateYaBo()&&&&&&&&{&&&&&&&&&&&&return new HuNanYaBo();&&&&&&&&}&&&&&&&&&// 制作湖南鸭架&&&&&&&&public override YaJia CreateYaJia()&&&&&&&&{&&&&&&&&&&&&return new HuNanYajia();&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 湖南的鸭脖&&&&/// &/summary&&&&&public class HuNanYaBo : YaBo&&&&{&&&&&&&&public override void Print()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("湖南的鸭脖");&&&&&&&&}&&&&}&&&&&/// &summary&&&&&/// 湖南的鸭架&&&&/// &/summary&&&&&public class HuNanYajia : YaJia&&&&{&&&&&&&&public override void Print()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("湖南的鸭架子");&&&&&&&&}&&&&}
此时,只需要添加三个类:一个是湖南具体工厂类,负责创建湖南口味的鸭脖和鸭架,另外两个类是具有湖南口味的鸭脖类和鸭架类。从上面代码看出,抽象工厂对于系列产品的变化支持 “开放——封闭”原则(指的是要求系统对扩展开放,对修改封闭),扩展起来非常简便,但是,抽象工厂对于添加新产品这种情况就不支持”开放——封闭 “原则,这也是抽象工厂的缺点所在,这点会在第四部分详细介绍。
三、抽象工厂的分析
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这真是抽象工厂模式的优点所在,然后抽象模式同时也存在不足的地方。下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):
抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
知道了抽象工厂的优缺点之后,也就能很好地把握什么情况下考虑使用抽象工厂模式了,下面就具体看看使用抽象工厂模式的系统应该符合那几个前提:
一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
这个系统有多个系列产品,而系统中只消费其中某一系列产品
系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。
四、.NET中抽象工厂模式实现
抽象工厂模式在实际中的应用也是相当频繁的,然而在我们.NET类库中也存在应用抽象工厂模式的类,这个类就是mon.DbProviderFactory,这个类位于System.Data.dll程序集中,该类扮演抽象工厂模式中抽象工厂的角色,我们可以用reflector反编译工具查看该类的实现:
/// 扮演抽象工厂的角色
/// 创建连接数据库时所需要的对象集合,
/// 这个对象集合包括有 DbConnection对象(这个是抽象产品类,如绝味例子中的YaBo类)、DbCommand类、DbDataAdapter类,针对不同的具体工厂都需要实现该抽象类中方法,
public abstract class DbProviderFactory
// 提供了创建具体产品的接口方法
protected DbProviderFactory();
public virtual DbCommand CreateCommand();
public virtual DbCommandBuilder CreateCommandBuilder();
public virtual DbConnection CreateConnection();
public virtual DbConnectionStringBuilder CreateConnectionStringBuilder();
public virtual DbDataAdapter CreateDataAdapter();
public virtual DbDataSourceEnumerator CreateDataSourceEnumerator();
public virtual DbParameter CreateParameter();
public virtual CodeAccessPermission CreatePermission(PermissionState state);
12345678910111213141516
/// 扮演抽象工厂的角色/// 创建连接数据库时所需要的对象集合,/// 这个对象集合包括有 DbConnection对象(这个是抽象产品类,如绝味例子中的YaBo类)、DbCommand类、DbDataAdapter类,针对不同的具体工厂都需要实现该抽象类中方法,public abstract class DbProviderFactory{&&&&// 提供了创建具体产品的接口方法&&&&protected DbProviderFactory();&&&&public virtual DbCommand CreateCommand();&&&&public virtual DbCommandBuilder CreateCommandBuilder();&&&&public virtual DbConnection CreateConnection();&&&&public virtual DbConnectionStringBuilder CreateConnectionStringBuilder();&&&&public virtual DbDataAdapter CreateDataAdapter();&&&&public virtual DbDataSourceEnumerator CreateDataSourceEnumerator();&&&&public virtual DbParameter CreateParameter();&&&&public virtual CodeAccessPermission CreatePermission(PermissionState state);}
DbProviderFactory类是一个抽象工厂类,该类提供了创建数据库连接时所需要的对象集合的接口,实际创建的工作在其子类工厂中进行,微软使用的是SQL Server数据库,因此提供了连接SQL Server数据的具体工厂实现,具体代码可以用反编译工具查看,具体代码如下:
/// 扮演着具体工厂的角色,用来创建连接SQL Server数据所需要的对象
public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider
public static readonly SqlClientFactory Instance = new SqlClientFactory();
// 构造函数
private SqlClientFactory()
// 重写抽象工厂中的方法
public override DbCommand CreateCommand()
// 创建具体产品
return new SqlCommand();
public override DbCommandBuilder CreateCommandBuilder()
return new SqlCommandBuilder();
public override DbConnection CreateConnection()
return new SqlConnection();
public override DbConnectionStringBuilder CreateConnectionStringBuilder()
return new SqlConnectionStringBuilder();
public override DbDataAdapter CreateDataAdapter()
return new SqlDataAdapter();
public override DbDataSourceEnumerator CreateDataSourceEnumerator()
return SqlDataSourceEnumerator.I
public override DbParameter CreateParameter()
return new SqlParameter();
public override CodeAccessPermission CreatePermission(PermissionState state)
return new SqlClientPermission(state);
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
/// 扮演着具体工厂的角色,用来创建连接SQL Server数据所需要的对象public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider{&&&&// Fields&&&&public static readonly SqlClientFactory Instance = new SqlClientFactory();&&& // 构造函数&&&&private SqlClientFactory()&&&&{&&&&}&&&&&& // 重写抽象工厂中的方法&&&&public override DbCommand CreateCommand()&&&&{&&// 创建具体产品&&&&&&&&return new SqlCommand();&&&&}&&&&&public override DbCommandBuilder CreateCommandBuilder()&&&&{&&&&&&&&return new SqlCommandBuilder();&&&&}&&&&&public override DbConnection CreateConnection()&&&&{&&&&&&&&return new SqlConnection();&&&&}&&&&&public override DbConnectionStringBuilder CreateConnectionStringBuilder()&&&&{&&&&&&&&return new SqlConnectionStringBuilder();&&&&}&&&&&public override DbDataAdapter CreateDataAdapter()&&&&{&&&&&&&&return new SqlDataAdapter();&&&&}&&&&&public override DbDataSourceEnumerator CreateDataSourceEnumerator()&&&&{&&&&&&&&return SqlDataSourceEnumerator.Instance;&&&&}&&&&&public override DbParameter CreateParameter()&&&&{&&&&&&&&return new SqlParameter();&&&&}&&&&&public override CodeAccessPermission CreatePermission(PermissionState state)&&&&{&&&&&&&&return new SqlClientPermission(state);&&&&}}
因为微软只给出了连接SQL Server的具体工厂的实现,我们也可以自定义连接Oracle、MySql的具体工厂的实现。
到这里,抽象工厂模式的介绍就结束,在下一专题就将为大家介绍建造模式。
程序源码:
可能感兴趣的话题
觉得这个也可以用工厂方法实现呀,像这样
public abstract class JueWei
public abstract void Yabo();
public abstract void YaJia();
public class SHJueWei:JueWei
public override void Yabo()
Console.WriteLine("上海鸭脖");
public override void YaJia()
Console.WriteLine("上海鸭架");
public abstract class JWFactory
public abstract JueWei CreatFactory();
public class SHJWFactory:JWFactory
public override JueWei CreatFactory()
return new SHJueWei();
static void Main(string[] args)
SHJWFactory shjwf = new SHJWFactory();
JueWei shjw = shjwf.CreatFactory();
shjw.Yabo();
shjw.YaJia();
Console.Read();
1234567891011121314151617181920212223242526272829303132333435
public abstract class JueWei&&&&{&&&&&&&&public abstract void Yabo();&&&&&&&&public abstract void YaJia();&&&&}&&&&public class SHJueWei:JueWei&&&&{&&&&&&&&public override void Yabo()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("上海鸭脖");&&&&&&&&}&&&&&&&&public override void YaJia()&&&&&&&&{&&&&&&&&&&&&Console.WriteLine("上海鸭架");&&&&&&&&}&&&&}&&&&public abstract class JWFactory&&&&{&&&&&&&&public abstract JueWei CreatFactory();&&&&}&&&&public class SHJWFactory:JWFactory&&&&{&&&&&&&&public override JueWei CreatFactory()&&&&&&&&{&&&&&&&&&&&&return new SHJueWei();&&&&&&&&}&&&&}&& static void Main(string[] args)&&&&&&&&{&&&&&&&&&&&&SHJWFactory shjwf = new SHJWFactory();&&&&&&&&&&&&JueWei shjw = shjwf.CreatFactory();&&&&&&&&&&&&shjw.Yabo();&&&&&&&&&&&&shjw.YaJia();&&&&&&&&&&&&Console.Read();&&&&&&&&}
求指点,难道是我理解错了+_+
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
&#8211; 好的话题、有启发的回复、值得信赖的圈子
&#8211; 分享和发现有价值的内容与观点
&#8211; 为IT单身男女服务的征婚传播平台
&#8211; 优秀的工具资源导航
&#8211; 翻译传播优秀的外文文章
&#8211; 国内外的精选文章
&#8211; UI,网页,交互和用户体验
&#8211; 专注iOS技术分享
&#8211; 专注Android技术分享
&#8211; JavaScript, HTML5, CSS
&#8211; 专注Java技术分享
&#8211; 专注Python技术分享
& 2016 伯乐在线}

我要回帖

更多关于 抽象工厂模式 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信