设计模式—工厂模式(Factory Pattern)

来源:互联网 发布:mysql fetch object 编辑:程序博客网 时间:2024/06/06 07:28

工厂模式主要是为创建对象的提供接口,按照《Java与模式》书中提到的,可以分为三种:

1.简单工厂模式

2.工厂方法模式

3.抽象工厂模式

接下来,我将逐个介绍。

1.简单工厂模式

它有三个部分组成:

1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

UML图:


抽象产品类

public abstract class Product {    public abstract void Opration();}


具体产品类:

public class ProductA extends Product {//具体产品A@Overridepublic void Opration() {System.out.println("ProductA Opration");}}public class ProductB extends Product {//具体产品B@Overridepublic void Opration() {System.out.println("ProductB Opration");}}

简单工厂类:

public class SimpleProductFactory {private static Product product = null;public static Product CreateProduct(String productType) {switch (productType) {case "A":product = new ProductA();break;case "B":product = new ProductB();break;}return product;}

客户端类:

public class ClientTest {public static void main(String[] args) {Product product = SimpleProductFactory.CreateProduct("A");product.Opration();}}

简单工厂模式的优缺点分析:

     优点:工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。

      缺点:由于工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;而且由于简单工厂模式的产品室基于一个共同的抽象类或者接口,这样一来,但产品的种类增加的时候,即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。而且更重要的是,简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,因为当我新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。

      总结一下:简单工厂模式分离产品的创建者和消费者,有利于软件系统结构的优化;但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了“开放封闭原则”。另外,简单工厂模式的方法一般都是静态的,而静态工厂方法是无法让子类继承的,因此,简单工厂模式无法形成基于基类的继承树结构。

简单工厂模式的实际应用简介: 

         作为一个最基本和最简单的设计模式,简单工厂模式却有很非常广泛的应用,我们这里以Java中的JDBC操作数据库为例来说明。

       JDBC是SUN公司提供的一套数据库编程接口API,它利用Java语言提供简单、一致的方式来访问各种关系型数据库。Java程序通过JDBC可以执行SQL语句,对获取的数据进行处理,并将变化了的数据存回数据库,因此,JDBC是Java应用程序与各种关系数据进行对话的一种机制。用JDBC进行数据库访问时,要使用数据库厂商提供的驱动程序接口与数据库管理系统进行数据交互。

       客户端要使用使用数据时,只需要和工厂进行交互即可,这就导致操作步骤得到极大的简化,操作步骤按照顺序依次为:注册并加载数据库驱动,一般使用Class.forName();创建与数据库的链接Connection对象;创建SQL语句对象preparedStatement

(sql);提交SQL语句,根据实际情况使用executeQuery()或者executeUpdate();显示相应的结果;关闭数据库。



2.工厂方法模式

它有四种组成:

(1)抽象工厂角色:这是工厂方法模式的核心,与应用程序无关。是具体工厂角色必须实现的接口或者继承的父类。在java中用抽象类或者接口来实现。

(2)具体工厂角色:它含有和具体业务逻辑的代码。由应用程序调用以创建对应的具体产品的对象。在java中往往有一个具体类实现;

(3)抽象产品角色:同简单工厂模式介绍;

(4)具体产品角色:同简单工厂模式介绍;

与简单工厂模式对比,工厂方法模式多了一个抽象工厂角色。

UML图:


接下来看一个具体实例:

抽象产品类和具体产品类的代码和前面的一样;


抽象工厂类:

public abstract class AbstractProductFactory {public abstract Product createProduct();}

具体工厂类:

//具体工厂A

public class ProductAFactory extends AbstractProductFactory {@Overridepublic ProductA createProduct() {return new ProductA();}}//具体工厂Bpublic class ProductBFactory extends AbstractProductFactory {@Overridepublic ProductB createProduct() {return new ProductB();}}

客户端类:

public class ClientTest {public static void main(String[] args) {ProductAFactory productAFactory = new ProductAFactory();ProductA productA = productAFactory.createProduct();productA.Opration();}}

工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的工厂类。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。可以看出工厂角色的结构也是符合开闭原则的!

问题:

可以看出工厂方法的加入,使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。所以我建议在这种情况下使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。当然特殊的情况,就要特殊对待了:对于系统中存在不同的产品树,而且产品树上存在产品族。那么这种情况下就可能可以使用抽象工厂模式了。


启迪:如果不使用工厂模式来实现我们的例子,也许代码会减少很多——只需要实现已有的产品,不使用多态。但是在可维护性上,可扩展性上是非常差的(你可以想象一下添加一个产品后要牵动的类)。因此为了提高扩展性和维护性,多写些代码是值得的。


3.抽象工厂模式

      在介绍抽象工厂模式中,首先介绍一下产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。我们拿生产汽车的例子来说明他们之间的区别。


       在上面的类图中,两厢车和三厢车称为两个不同的等级结构;而2.0排量车和2.4排量车则称为两个不同的产品族。再具体一点,2.0排量两厢车和2.4排量两厢车属于同一个等级结构,2.0排量三厢车和2.4排量三厢车属于另一个等级结构;而2.0排量两厢车和2.0排量三厢车属于同一个产品族,2.4排量两厢车和2.4排量三厢车属于另一个产品族。


它的四个组成:

和工厂方法模式类似。


UML图:

、、


看一个例子

//抽象产品1interface IProduct1 {public void show();}//抽象产品2interface IProduct2 {public void show();}//具体产品1class Product1 implements IProduct1 {public void show() {System.out.println("这是1型产品");}}//具体产品2class Product2 implements IProduct2 {public void show() {System.out.println("这是2型产品");}}//抽象工厂interface IFactory {public IProduct1 createProduct1();public IProduct2 createProduct2();}//具体工厂class Factory implements IFactory{public IProduct1 createProduct1() {return new Product1();}public IProduct2 createProduct2() {return new Product2();}}//客户类public class Client {public static void main(String[] args){IFactory factory = new Factory();factory.createProduct1().show();factory.createProduct2().show();}}

抽象工厂模式的优缺点分析

优点抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

缺点 产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

适用场景

       当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。


总结

       无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。

       所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。


参考:抽象设计模式    设计模式--工厂模式     工厂模式
0 0
原创粉丝点击