`

简单工程模式 工厂模式 抽象工厂模式

    博客分类:
  • java
阅读更多
http://www.cnblogs.com/poissonnotes/archive/2010/12/01/1893871.html

工厂模式 

一、引子
话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰)、Bmw(宝马)、Audi(奥迪)看来这人比较爱国,没有日本车),还雇了司机为他开车。不过,爆发户坐车时总是这样:上Benz车后跟司机说"开奔驰车!",坐上Bmw后他说"开宝马车!",坐上Audi后他说"开奥迪车!"。你一定说:这人有病!直接说开车不就行了?! 而当把这个爆发户的行为放到我们程序语言中来,我们发现C语言一直是通过这种方式来坐车的!幸运的是,这种有病的现象在OO语言中可以避免了。下面以Java语言为基础来引入我们本文的主题:工厂模式!! 

二、简介
工厂模式主要是为创建对象提供了接口。工厂模式按照《Java与模式》中的提法分为三类:
1. 简单工厂模式(Simple Factory) 
2. 工厂方法模式(Factory Method) 
3. 抽象工厂模式(Abstract Factory) 
这三种模式从上到下逐步抽象,并且更具一般性。还有一种分类法,就是将简单工厂模式看为工厂方法模式的一种特例,两个归为一类。下面是使用工厂模式的两种情况:
1.在编码时不能预见需要创建哪种类的实例。
2.系统不应依赖于产品类实例如何被创建、组合和表达的细节 

三、简单工厂模式
顾名思义,这个模式本身很简单,而且使用在业务较简单的情况下。
它由三种角色组成(关系见下面的类图):
1、工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。 

2、抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。 

3、具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
clip_image002
那么简单工厂模式怎么用呢?我来举个例子吧,我想这个比讲一大段理论上的文字描述要容易理解的多!下面就来给那个暴发户治病: P 
在使用了简单工厂模式后,现在暴发户只需要坐在车里对司机说句:"开车"就可以了。来看看怎么实现的:
//抽象产品角色
 public interface Car{ 
 public void drive(); 
 }
  
 //具体产品角色
 public class Benz implements Car{ 
 public void drive() { 
 System.out.println("Driving Benz "); 
 } 
 }
  
 public class Bmw implements Car{ 
 public void drive() { 
 System.out.println("Driving Bmw "); 
 } 
 } 
 。。。(奥迪我就不写了:P)
  
 //工厂类角色
 public class Driver{
  
 //工厂方法
 //注意 返回类型为抽象产品角色
 public static Car driverCar(String s)throws Exception {
  
 //判断逻辑,返回具体的产品角色给Client 
 if(s.equalsIgnoreCase("Benz")) return new Benz(); 
 else if(s.equalsIgnoreCase("Bmw")) 
 return new Bmw();
  
 ...... 
 else throw new Exception(); 
 。。。
  
 //欢迎暴发户出场...... 
 public class Magnate{ 
 public static void main(String[] args){ 
 try{ 
 //告诉司机我今天坐奔驰
 Car car = Driver.driverCar("benz"); 
 //下命令:开车
 car.drive(); 
 。。。
如果将所有的类放在一个文件中,请不要忘记只能有一个类被声明为public。 程序中类之间的关系如下:

这便是简单工厂模式了。下面是其好处: 

首先,使用了简单工厂模式后,我们的程序不在"有病",更加符合现实中的情况;而且客户端免除了直接创建产品对象的责任,而仅仅负责"消费"产品(正如暴发户所为)。
下面我们从开闭原则上来分析下简单工厂模式。当暴发户增加了一辆车的时候,只要符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。那么对于产品部分来说,它是符合开闭原则的--对扩展开放、对修改关闭;但是工厂部分好像不太理想,因为每增加一辆车,都要在工厂类中增加相应的商业逻辑和判断逻辑,这显自然是违背开闭原则的。
对于这样的工厂类(在我们的例子中是为司机师傅),我们称它为全能类或者上帝类。
我们举的例子是最简单的情况,而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝类坏了,进而累坏了我们可爱的程序员:( 
正如我前面提到的简单工厂模式适用于业务将简单的情况下。而对于复杂的业务环境可能不太适应阿。这就应该由工厂方法模式来出场了!! 

四、工厂方法模式
先来看下它的组成吧:
1、抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2、具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
3、抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4、具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
来用类图来清晰的表示下的它们之间的关系:


我们还是老规矩使用一个完整的例子来看看工厂模式各个角色之间是如何来协调的。话说暴发户生意越做越大,自己的爱车也越来越多。这可苦了那位司机师傅了,什么车它都要记得,维护,都要经过他来使用!于是暴发户同情他说:看你跟我这么多年的份上,以后你不用这么辛苦了,我给你分配几个人手,你只管管好他们就行了!于是,工厂方法模式的管理出现了。代码如下:
//抽象产品角色,具体产品角色与简单工厂模式类似,只是变得复杂了些,这里略。
//抽象工厂角色
 public interface Driver{ 
 public Car driverCar(); 
 } 
 public class BenzDriver implements Driver{ 
 public Car driverCar(){ 
 return new Benz(); 
 } 
 } 
 public class BmwDriver implements Driver{ 
 public Car driverCar() { 
 return new Bmw(); 
 } 
 } 
 ......//应该和具体产品形成对应关系,这里略... 
 //有请暴发户先生
 public class Magnate 
 { 
 public static void main(String[] args) 
 { 
 try{ 
 Driver driver = new BenzDriver();
  
 Car car = driver.driverCar(); 
 car.drive(); 
 }catch(Exception e) 
 { } 
 } 
 } 
工厂方法使用一个抽象工厂角色作为核心来代替在简单工厂模式中使用具体类作为核心。让我们来看看工厂方法模式给我们带来了什么?使用开闭原则来分析下工厂方法模式。当有新的产品(即暴发户的汽车)产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。看来,工厂方法模式是完全符合开闭原则的!
使用工厂方法模式足以应付我们可能遇到的大部分业务需求。但是当产品种类非常多时,就会出现大量的与之对应的工厂类,这不应该是我们所希望的。所以我建议在这种情况下使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。
当然特殊的情况,就要特殊对待了:对于系统中存在不同的产品树,而且产品树上存在产品族,那么这种情况下就可能可以使用抽象工厂模式了。

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

六、抽象工厂模式
先来认识下什么是产品族:位于不同产品等级结构中,功能相关联的产品组成的家族。如果光看这句话就能清楚的理解这个概念,我不得不佩服你啊。还是让我们用一个例子来形象地说明一下吧。 

图中的BmwCar和BenzCar就是两个产品树(产品层次结构);而如图所示的BenzSportsCar和BmwSportsCar就是一个产品族。他们都可以放到跑车家族中,因此功能有所关联。同理BmwBussinessCar和BenzSportsCar也是一个产品族。
回到抽象产品模式的话题上,可以这么说,它和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象。而且使用抽象工厂模式还要满足一下条件:
1.系统中有多个产品族,而系统一次只可能消费其中一族产品
2.同属于同一个产品族的产品以其使用。
来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):
抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现
看过了前两个模式,对这个模式各个角色之间的协调情况应该心里有个数了,我就不举具体的例子了。只是一定要注意满足使用抽象工厂模式的条件哦,不然即使存在了多个产品树,也存在产品族,但是不能使用的。



  • 大小: 14.1 KB
  • 大小: 23 KB
  • 大小: 29.9 KB
分享到:
评论

相关推荐

    抽象工厂模式+反射技术(抽象工厂模式+简单工厂模式)

    在软件工程中,当系统需要在运行时选择不同的产品族时,或者想要隔离具体产品的实现细节时,抽象工厂模式就显得尤为重要。 首先,我们来看一下“抽象工厂模式+反射技术”。在Java或其他面向对象的语言中,反射是一...

    简单工厂模式、工厂模式、抽象工厂模式案例(C++实现)

    在这个压缩包中,包含了三种工厂模式的C++实现:简单工厂模式、工厂方法模式以及抽象工厂模式。让我们一一探讨这些模式。 1. 简单工厂模式: 简单工厂模式是一种静态工厂方法,它提供一个公共的工厂类来创建对象。...

    设计模式抽象工厂实验报告

    ### 抽象工厂模式实验报告知识点解析 #### 实验背景及目标 本次实验报告来源于南京工程学院软件设计与体系结构课程。实验的核心在于理解和实践**抽象工厂模式**,这是一种常用的面向对象设计模式,旨在解决软件...

    肯德基:抽象工厂模式

    抽象工厂模式是软件工程中常用的一种创建型设计模式,它的核心思想是为创建一组相关或相互依赖的对象提供一个接口,而不需要指定它们具体的类。在Java中,抽象工厂模式被广泛应用,它有助于整合代码,提高系统的可...

    三种设计模式(简单工厂_工厂方法_抽象工厂)

    抽象工厂模式是最为复杂的一种工厂模式,它提供了创建相关或依赖对象的家族,而无需指定它们的具体类。这种模式主要用于当产品族中的对象需要一起使用时,确保它们都属于同一产品等级结构。抽象工厂可以确保客户端...

    C++ 工厂模式 (简单工厂、工厂和抽象工厂)

    例如,在图形界面设计中,可以有Windows风格的按钮、文本框和滚动条,以及Mac OS风格的对应组件,抽象工厂模式可以确保在不修改客户端代码的情况下,统一更换整个应用程序的界面风格。 #### 六、实现与应用 在实际...

    走进设计模式之抽象工厂(Abstract Factory)

    抽象工厂模式的核心在于抽象工厂类,它定义了一组创建对象的接口,这些对象属于同一族(或称为“产品族”)。每个具体工厂类都是抽象工厂的一个实现,负责生产特定族的产品。例如,如果我们的系统需要处理不同平台...

    C#抽象工厂模式案例代码

    抽象工厂模式是一种面向对象的设计模式,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。在C#中,这种模式经常用于软件工程中的框架设计,允许系统独立于具体产品的实现进行扩展和修改。...

    设计模式(简单工厂,工厂,抽象工厂)简单例子.rar

    本篇文章将深入探讨三种创建型设计模式:简单工厂模式、工厂方法模式和抽象工厂模式,通过生动的比喻以及实际应用的例子,揭示它们各自的特点和应用场景。 首先,我们从简单工厂模式开始。简单工厂模式是一种创建型...

    抽象工厂模式Demo

    在软件工程中,当系统需要与多个平台或环境交互时,抽象工厂模式特别有用,因为它允许在运行时选择不同的实现。 抽象工厂模式包含以下几个角色: 1. 抽象工厂(Abstract Factory):这是核心接口,定义了创建一系列...

    设计模式中抽象工厂模式的一个例子

    抽象工厂模式是设计模式中的一种,属于创建型模式,它提供了一个创建对象的接口,但允许子类决定实例化哪些类。这个模式的关键在于为一组相关或相互依赖的对象提供一个统一的接口,而无需指定他们的具体实现。 抽象...

    抽象工程模式

    在软件工程中,抽象工厂模式常常用于构建复杂的系统,其中组件之间可能存在跨平台或者跨系统的依赖关系。 抽象工厂模式包含以下角色: 1. 抽象工厂(Abstract Factory):定义一个创建对象的接口,但不指定具体的...

    抽象工厂设计模式实例

    在软件工程中,当我们需要创建一系列相关或相互依赖的对象时,但又不想指定它们具体的类,抽象工厂模式就能派上用场。这个模式尤其适用于那些具有多种平台或者环境,需要创建平台特定的对象的情况。 在C#中实现抽象...

    JAVA设计模式之抽象工厂

    在Java中,抽象工厂模式通常用于创建一组相关的或相互依赖的对象,而无需指定它们的具体类。这种模式的关键在于抽象工厂类,它定义了一组接口,用于创建不同产品族的实例。产品族是一组相关或相互依赖的对象,而产品...

    JAVA设计模式研究之抽象工厂模式

    在抽象工厂模式之前,有两个基础的工厂模式:简单工厂模式和工厂方法模式。 2.1 简单工厂模式:在简单工厂模式中,工厂类包含了一个用于创建对象的静态方法。这种方法适用于产品种类较少的情况,但当需要添加新产品...

    概括设计模式,举例详解抽象工厂模式

    ### 概述设计模式:以抽象工厂模式为例深入解析 设计模式是在软件工程领域中,为解决特定问题而总结出的、经过验证的解决方案。它们是开发者在长期实践中提炼出来的智慧结晶,旨在提高代码的可读性、可维护性和可...

    软件设计模式——抽象工厂

    抽象工厂模式是一种重要的软件设计模式,它属于创建型模式,主要解决的是当系统需要创建一系列相关或相互依赖的对象时,而这些对象的类在运行时可能不确定的问题。在这个模式中,我们通过一个抽象工厂接口来定义创建...

    设计模式之-抽象工厂-AbstractFactory

    抽象工厂模式可以帮助我们创建一个工厂接口,该接口声明了创建这些组件的方法,然后为每种操作系统实现一个具体的工厂类。 ```java // 抽象工厂接口 public interface GUIFactory { Button createButton(); ...

Global site tag (gtag.js) - Google Analytics