Java设计模式之三种工厂模式

Wesley13
• 阅读 568

工厂模式实现了创建者和调用者的分离,实现了更好的解耦。

详细分类:

  1. 简单工厂模式(静态工厂模式);

  2. 工厂方法模式;

  3. 抽象工厂模式

面向对象设计的基本原则:

1)       **OCP(开闭原则, Open-Closed Principle)**:一个软件的实体应当对扩展开放,对修改关闭。

2)       **DIP(依赖倒转原则,Dependence Inversion Principle)**:要针对接口编程,不要针对实现编程。

3)       **LoD(迪米特法则, Law of Demeter)**:只与你直接的朋友通信,而避免和陌生人通信。

一、简单工厂模式(静态工厂模式)

我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类。

1 public abstract class INoodles {
2     /**
3      * 描述每种面条啥样的
4      */
5     public abstract void desc();
6 }

先来一份兰州拉面(具体的产品类):

1 public class LzNoodles extends INoodles {
2     @Override
3     public void desc() {
4         System.out.println("兰州拉面 上海的好贵 家里才5 6块钱一碗");
5     }
6 }

程序员加班必备也要吃泡面(具体的产品类):

1 public class PaoNoodles extends INoodles {
2     @Override
3     public void desc() {
4         System.out.println("泡面好吃 可不要贪杯");
5     }
6 }

还有我最爱吃的家乡的干扣面(具体的产品类):

1 public class GankouNoodles extends INoodles {
2     @Override
3     public void desc() {
4         System.out.println("还是家里的干扣面好吃 6块一碗");
5     }
6 }

准备工作做完了,我们来到一家“简单面馆”(简单工厂类),菜单如下:

 1 public class SimpleNoodlesFactory {
 2     public static final int TYPE_LZ = 1;//兰州拉面
 3     public static final int TYPE_PM = 2;//泡面
 4     public static final int TYPE_GK = 3;//干扣面
 5 
 6     public static INoodles createNoodles(int type) {
 7         switch (type) {
 8             case TYPE_LZ:
 9                 return new LzNoodles();
10             case TYPE_PM:
11                 return new PaoNoodles();
12             case TYPE_GK:
13             default:
14                 return new GankouNoodles();
15         }
16     }
17 }

简单面馆就提供三种面条(产品),你说你要啥,他就给你啥。这里我点了一份干扣面:

1 /**
2  * 简单工厂模式
3  */
4  INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK);
5  noodles.desc()

要点:
1)简单工厂模式也叫静态工厂模式,就是工厂类一般使用静态方法,通过接收的参数的不同的对象的不同来返回不同的对象实例。
2)对于增加新产品无能为力!不修改代码的话,是无法扩展的。
3)一般使用较多还是简单工厂模式。

二、工厂方法模式

工厂方法模式要点:

1)为了避免简单工厂模式的缺点,不完全满足**OCP(开闭原则)**。

2)工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。

Car.java接口的源码:

工厂方法模式更加符合开闭原则弊端是每次扩展都会增加新的类。

三、简单工厂模式和工厂方法模式PK

1)结构复杂度

从这个角度比较,显然简单工厂模式要占优,简单工厂模式只需要一个工厂类,而工厂方法模式的工厂类随着产品类的个数增加而增加,这无疑会使类的个数越来越多,从而增加了结构的复杂程度。

2)代码复杂度

代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面肯定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增加需要增加更多方法(或代码)。

3)客户端编程难度

工厂方法模式虽然在工厂类结构中引入了接口从而满足了OCP,但是在客户端编码中需要对工厂类进行实例化。而简单工厂模式的工厂类是个静态类,在客户端无需实例化,这无疑是个吸引人的优点。

4)管理上的难度

这是个关键的问题。

我们先谈扩展。众所周知,工厂方法模式完全满足OCP,即它有非常良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否定的,简单工厂模式同样具备良好的扩展性-----扩展的时候仅需要修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求了。尽管这没有完全满足OCP,但我们不需要太拘泥于设计理论,要知道,sun提供的java官方工具包中也有很多没有满足OCP的例子啊。

然后我们从维护性的角度分析下,假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。反而简单工厂没有这些问题,当多个产品类需要修改时,简单工厂模式仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。

根据设计理论建议:工厂方法模式。但实际上,我们一般都用了简单工厂模式

四、抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

类型:创建类模式

类图:

Java设计模式之三种工厂模式

抽象工厂模式与工厂方法模式的区别

抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。

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

Java设计模式之三种工厂模式

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

明白了等级结构和产品族的概念,就理解工厂方法模式和抽象工厂模式的区别了,如果工厂的产品全部属于同一个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式。在本例中,如果一个工厂模式提供2.0排量两厢车和2.4排量两厢车,那么他属于工厂方法模式;如果一个工厂模式是提供2.4排量两厢车和2.4排量三厢车两个产品,那么这个工厂模式就是抽象工厂模式,因为他提供的产品是分属两个不同的等级结构。当然,如果一个工厂提供全部四种车型的产品,因为产品分属两个等级结构,他当然也属于抽象工厂模式了。

 1 interface IProduct1 {  
 2     public void show();  
 3 }  
 4 interface IProduct2 {  
 5     public void show();  
 6 }  
 7   
 8 class Product1 implements IProduct1 {  
 9     public void show() {  
10         System.out.println("这是1型产品");  
11     }  
12 }  
13 class Product2 implements IProduct2 {  
14     public void show() {  
15         System.out.println("这是2型产品");  
16     }  
17 }  
18   
19 interface IFactory {  
20     public IProduct1 createProduct1();  
21     public IProduct2 createProduct2();  
22 }  
23 class Factory implements IFactory{  
24     public IProduct1 createProduct1() {  
25         return new Product1();  
26     }  
27     public IProduct2 createProduct2() {  
28         return new Product2();  
29     }  
30 }  
31   
32 public class Client {  
33     public static void main(String[] args){  
34         IFactory factory = new Factory();  
35         factory.createProduct1().show();  
36         factory.createProduct2().show();  
37     }  
38 }

抽象工厂模式的优点:

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

抽象工厂模式的缺点:

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

适用场景:

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

工厂模式要点:

1)简单工厂模式(静态工厂模式)     虽然某种程度不符合设计原则,但实际使用最多。

2)工厂方法模式    不修改已有类的前提下,通过增加新的工厂类实现扩展。

3)抽象工厂模式    不可以增加产品,可以增加产品族

应用场景:

1)JDK中Calendar的getInstance方法

2)JDBC中Connection对象的获取;

3)Hibernate中SessionFactory创建Session;

4)Spring中IOC容器创建管理bean对象

5)XML解析时的DocumentBuilderFactory创建解析器对象;

6)反射中Class对象的newInstance()。

点赞
收藏
评论区
推荐文章
happlyfox happlyfox
3年前
笑说设计模式-小白逃课被点名
关于我简介工厂模式(FactoryPattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。分类工厂模式可以分为三种,其中简单工厂一般不被认为是一种设计模式,可以将其看成是工厂方法的一种特殊
zdd小小菜鸟 zdd小小菜鸟
1年前
创建型-2-抽象工厂模式( Abstract Factory Pattern )
创建型2抽象工厂模式(AbstractFactoryPattern)抽象工厂模式(AbstractFactoryPattern)是围绕一个超级工厂创建其他工厂tex该超级工厂又称为其他工厂的工厂在抽象
Wesley13 Wesley13
2年前
Unity C# 设计模式(二)简单工厂模式
定义:简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactoryMethod)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该
Wesley13 Wesley13
2年前
Java描述设计模式(04):抽象工厂模式
一、抽象工厂模式1、生活场景汽车生产根据用户选择的汽车类型,指定不同的工厂进行生产,选择红旗轿车,就要使用中国工厂,选择奥迪轿车,就要使用德国工厂。2、抽象工厂模式1.抽象工厂模式:定义了一个interface用于创建相关对象或相互依赖的对象,而无需指明具体的类;2.抽象工厂模式可以
Wesley13 Wesley13
2年前
Java进阶篇设计模式之三
前言在上一篇(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxuwujing%2Fp%2F9363142.html)中我们学习了工厂模式,介绍了简单工厂模式、工厂方法和抽象工厂模式。本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式。
Wesley13 Wesley13
2年前
Java中23种设计模式详解
Java中23种设计模式1\.设计模式31.1创建型模式41.1.1工厂方法41.1.2抽象工厂61.1.3建造者模式101.1.4单态模式131.1.5原型模式151.2结构型模式171.2.1适配器模式171.2.2桥接模式191.2.3组合
Stella981 Stella981
2年前
Python之设计模式
一、设计模式分类a、创建型模式简单工厂模式一、内容不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。二、角色工厂角色(Creator)抽象产品角色(Product)具体产品角色(ConcreteProduct)
Wesley13 Wesley13
2年前
C#设计模式 —— 工厂模式
。  工厂模式同样是项目中最常用的设计模式,工厂模式中又分为简单工厂,工厂方法,抽象工厂。下面我们由简单的开始逐一介绍。1.简单工厂模式  简单工厂又被称为静态工厂,在设计模式中属于创建型模式。主要解决的问题是封装了实例化的过程,通过传入参数来获不同实例。下面我们举一个项目中可能会用到的例子。  假设我们程序的数据保存在几个不同
Wesley13 Wesley13
2年前
C++ 深入浅出工厂模式(进阶篇)
介绍前文初始篇C深入浅出工厂模式(初始篇)(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxiaolincoding%2Fp%2F11524376.html),主要阐述了简单工厂模式、工厂方法模式和抽象工厂模式的结构、特点和缺陷等。以
Wesley13 Wesley13
2年前
23种设计模式(面向对象语言)
一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。所有的创建型模式都有两个主要功能:  1.将系统所使用的具体类的信息封装起来  2.隐藏