关闭

设计模式-----创建型之工厂模式

标签: 设计模式
123人阅读 评论(0) 收藏 举报
转载自:http://www.cnblogs.com/java-my-life/archive/2012/03/25/2416227.html

在阎宏博士的《JAVA与模式》一书中开头是这样描述工厂方法模式的:

  工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。

  工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

那么工厂方法模式是在什么场景下使用呢,下面就以本人的理解举例说明:

  相信很多人都做过导入导出功能,就拿导出功能来说。有这么一个需求:XX系统需要支持对数据库中的员工薪资进行导出,并且支持多种格式如:HTML、CSV、PDF等,每种格式导出的结构有所不同,比如:财务跟其他人对导出薪资的HTML格式要求可能会不一样,因为财务可能需要特定的格式方便核算或其他用途。

  如果使用简单工厂模式,则工厂类必定过于臃肿。因为简单工厂模式只有一个工厂类,它需要处理所有的创建的逻辑。假如以上需求暂时只支持3种导出的格式以及2种导出的结构,那工厂类则需要6个if else来创建6种不同的类型。如果日后需求不断增加,则后果不堪设想。

  这时候就需要工厂方法模式来处理以上需求。在工厂方法模式中,核心的工厂类不再负责所有的对象的创建,而是将具体创建的工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个类应当被实例化这种细节。

  这种进一步抽象化的结果,使这种工厂方法模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品,这一特点无疑使得工厂方法模式具有超过简单工厂模式的优越性。下面就针对以上需求设计UML图:

  从上图可以看出,这个使用的工厂方法模式的系统涉及到以下角色:

 

  抽象工厂(ExportFactory)角色:担任这个角色的是工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类实现。

  具体工厂(ExportHtmlFactory、ExportPdfFactory)角色:担任这个角色的是实现了抽象工厂接口的具体JAVA类。具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建导出类(如:ExportStandardHtmlFile)。

  抽象导出(ExportFile)角色:工厂方法模式所创建的对象的超类,也就是所有导出类的共同父类或共同拥有的接口。在实际的系统中,这个角色也常常使用抽象类实现。

  具体导出(ExportStandardHtmlFile等)角色:这个角色实现了抽象导出(ExportFile)角色所声明的接口,工厂方法模式所创建的每一个对象都是某个具体导出角色的实例。

源代码

  首先是抽象工厂角色源代码。它声明了一个工厂方法,要求所有的具体工厂角色都实现这个工厂方法。参数type表示导出的格式是哪一种结构,如:导出HTML格式有两种结构,一种是标准结构,一种是财务需要的结构。

public interface ExportFactory {
public ExportFile factory(String type);
}

  具体工厂角色类源代码:

复制代码
public class ExportHtmlFactory implements ExportFactory{

@Override
public ExportFile factory(String type) {
// TODO Auto-generated method stub
if("standard".equals(type)){

return new ExportStandardHtmlFile();

}else if("financial".equals(type)){

return new ExportFinancialHtmlFile();

}else{
throw new RuntimeException("没有找到对象");
}
}

}
复制代码
复制代码
public class ExportPdfFactory implements ExportFactory {

@Override
public ExportFile factory(String type) {
// TODO Auto-generated method stub
if("standard".equals(type)){

return new ExportStandardPdfFile();

}else if("financial".equals(type)){

return new ExportFinancialPdfFile();

}else{
throw new RuntimeException("没有找到对象");
}
}

}
复制代码

  抽象导出角色类源代码:

public interface ExportFile {
public boolean export(String data);
}

  具体导出角色类源代码,通常情况下这个类会有复杂的业务逻辑。

复制代码
public class ExportFinancialHtmlFile implements ExportFile{

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
System.out.println("导出财务版HTML文件");
return true;
}

}
复制代码
复制代码
public class ExportFinancialPdfFile implements ExportFile{

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
System.out.println("导出财务版PDF文件");
return true;
}

}
复制代码
复制代码
public class ExportStandardHtmlFile implements ExportFile{

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
System.out.println("导出标准HTML文件");
return true;
}

}
复制代码
复制代码
public class ExportStandardPdfFile implements ExportFile {

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
System.out.println("导出标准PDF文件");
return true;
}

}
复制代码

客户端角色类源代码:

复制代码
public class Test {

/**
*
@param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String data = "";
ExportFactory exportFactory = new ExportHtmlFactory();
ExportFile ef = exportFactory.factory("financial");
ef.export(data);
}

}
复制代码

工厂方法模式的活动序列图

  客户端创建ExportHtmlFactory对象,这时客户端所持有变量的静态类型为ExportFactory,而实际类型为ExportHtmlFactory。然后客户端调用ExportHtmlFactory对象的工厂方法factory(),接着后者调用ExportFinancialHtmlFile的构造子创建出导出对象。

工厂方法模式和简单工厂模式

  工厂方法模式和简单工厂模式在结构上的不同很明显。工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
  工厂方法模式退化后可以变得很像简单工厂模式。设想如果非常确定一个系统只需要一个具体工厂类,那么不妨把抽象工厂类合并到具体工厂类中去。由于只有一个具体工厂类,所以不妨将工厂方法改为静态方法,这时候就得到了简单工厂模式。

  如果系统需要加入一个新的导出类型,那么所需要的就是向系统中加入一个这个导出类以及所对应的工厂类。没有必要修改客户端,也没有必要修改抽象工厂角色或者其他已有的具体工厂角色。对于增加新的导出类型而言,这个系统完全支持“开-闭原则”。
  

完结

  一个应用系统是由多人开发的,导出的功能是你实现的,但是使用者(调用这个方法的人)可能却是其他人。这时候你应该设计的足够灵活并尽可能降低两者之间的耦合度,当你修改或增加一个新的功能时,使用者不需要修改任何地方。假如你的设计不够灵活,那么将无法面对客户多变的需求。可能一个极小的需求变更,都会使你的代码结构发生改变,并导致其他使用你所提供的接口的人都要修改他们的代码。牵一处而动全身,这就使得日后这个系统将难以维护。


0
0
查看评论

JS设计模式之创建型设计模式总结

JS设计模式: 创建型设计模式, 简单工厂模式, 工厂方法模式, 抽象工厂模式 原型模式, 单例模式
  • ganyingxie123456
  • ganyingxie123456
  • 2017-05-31 22:55
  • 295

设计模式(一) 工厂模式 五种写法总结

转载请标明出处: http://blog.csdn.net/zxt0601/article/details/52703280本文出自:【张旭童的博客】系列开篇瞎BB设计模式相关的文章学习与总结,一直有意为之,一直又觉得时机不到。一 是怕自己代码经验还不够,学习了也不懂,强行理解没有意义。二 是怕...
  • zxt0601
  • zxt0601
  • 2016-10-12 16:47
  • 14076

研磨设计模式之简单工厂模式(模式讲解)

3.1  典型疑问        首先来解决一个常见的疑问:可能有朋友会认为,上面示例中的简单工厂看起来不就是把客户端里面的“new Impl()”移动到简单工厂里面吗?不还是一样通过new一个实现类来得到接口吗?把“new Impl()”...
  • idwtwt
  • idwtwt
  • 2014-09-29 11:51
  • 278

设计模式-创建型之工厂模式

模式动机 在上一篇文章《设计模式-创建型之简单工厂模式》中,提到了简单工厂模式最大的缺点就是当需要新增产品时,必须修改工厂类,加入相应的逻辑。在简单工厂模式中,所有的产品都是由一个工厂类负责创建,可能会导致工厂类的逻辑复杂,不便于维护和扩展。因此,为了解决这些问题,工厂模式便诞生了!工厂模式与简...
  • ABC374744988
  • ABC374744988
  • 2015-08-10 21:23
  • 245

六种创建型设计模式的比较和总结

一、描述 创建型设计模式包括如下几个:简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、创建者模式(Builder)、原型模式(Prototype)、单例模式(Singleton)。 二、六种创建...
  • tongyuehong
  • tongyuehong
  • 2015-05-02 15:46
  • 1453

设计模式分类(创建型模式、结构型模式、行为模式)

1.创建型模式 前面讲过,社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象的使用分开也就成为了必然趋势。因为对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,它们分别是: 简单...
  • itpinpai
  • itpinpai
  • 2016-04-25 18:51
  • 8139

设计模式之工厂模式(创建型)

什么是设计模式? 每一个模式描述了我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。 1.简单工厂(Simple Factory) 当看到“new”时,就会想到“具体”。Pizza pizza = new CheesePizza();当...
  • xinwengong
  • xinwengong
  • 2014-10-11 23:22
  • 307

设计模式之三:工厂方法模式—多态工厂的实现

简单工厂的严重问题: 当系统中需要引进新产品时,静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,违背了开闭原则 引入工厂方法模式: 针对不同的产品提供不同的工厂 定义: 定义一个用于创建对象的接口,让子类决定将 哪一个类实例化,工厂方法迷失让一个类...
  • wujunwen
  • wujunwen
  • 2016-09-22 15:25
  • 696

调侃《Head First 设计模式》之工厂模式(二)

上一篇讲了简单工厂和工厂方法,在讲抽象工厂模式之前,现在先分析下简单工厂和工厂方法的主要特点和区别:简单工厂最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件实时动态实例化相关的类,对于客户端来说去除了与具体产品的依赖,增加新的产品种类不用修改客户端。最大的缺点是如果要增加新的产品种类...
  • sinat_23092639
  • sinat_23092639
  • 2015-04-18 20:50
  • 559

设计模式(创建型)之单例模式(Singleton Pattern)

单例模式可能是23种设计模式中最简单的。应用也非常广泛,譬如Android中的数据库访问等操作都可以运用单例模式。核心概念: 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。
  • yanbober
  • yanbober
  • 2015-04-27 16:50
  • 2680
    个人资料
    • 访问:76573次
    • 积分:811
    • 等级:
    • 排名:千里之外
    • 原创:13篇
    • 转载:62篇
    • 译文:0篇
    • 评论:5条
    最新评论