0

0

Java设计模式—工厂设计模式

高洛峰

高洛峰

发布时间:2016-12-15 13:46:37

|

2151人浏览过

|

来源于php中文网

原创

工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。
工厂模式的形态
工厂模式主要用一下几种形态:
1:简单工厂(simple factory)。
2:工厂方法(factory method)。
3:抽象工厂(abstract factory)。

简单工厂(simple factory)
又叫静态工厂,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。我们来看一个具体的例子:
假设一家工厂,几生产洗衣机,有生产冰箱,还有空调等等..
我们先为所有产品定义一个共同的产品接口

public interface Product{}


接着我们让这个工厂的所有产品都必须实现此接口

public class Washer implements Product{ 
   public Washer(){ 
       System.out.println("洗衣机被制造了"); 
   } 
} 
 
public class Icebox implements Product{ 
   public Icebox(){ 
       System.out.println("冰箱被制造了"); 
   } 
} 
 
public class AirCondition implements Product{ 
   public Icebox(){ 
       System.out.println("空调被制造了"); 
   } 
}


接下来我们来写一个工厂类,有它来负责生产以上的产品

public class SimpleFactory { 
     
    public static Product factory(String productName) throws Exception{ 
        if(productName.equals("Washer")){ 
            return new Washer(); 
        }else if(productName.equals("Icebox")){ 
            return new Icebox(); 
        }else if(productName.equals("AirCondition")){ 
            return new AirCondition(); 
        }else{ 
            throw new Exception("没有该产品"); 
        } 
    } 
}


好了,有了这个工厂类,我们就可以开始下定单了,SimpleFactory将根据不同的定单类决定生产什么产品。

public static void main(String[] args) { 
    try { 
              SimpleFactory.factory("Washer"); 
              SimpleFactory.factory("Icebox"); 
              SimpleFactory.factory("AirCondition"); 
            } catch (Exception e) { 
        e.printStackTrace(); 
    } 
}


由上面的代码可以看出,简单工厂的核心就是一个SimpleFactory类,他拥有必要的逻辑判断能力和所有产品的创建权利,我们只需要向把定单给他,就能得到我们想要的产品。这使用起来似乎非常方便。
但,实际上,这个SimpleFactory有很多的局限。首先,我们每次想要增加一种新产品的时候,都必须修改SimpleFactory的原代码。其次,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这对以后的维护简直就是恐怖两个字...
还有就是,整个系统都严重依赖SimpleFactory类,只要SimpleFactory类一出问题,系统就进入不能工作的状态,这也是最为致命的一点....
以上的不足将在工厂模式的另外两种状态中得到解决。

工厂方法(Factory Method)
上面的代码告诉我们,简单工厂并不简单,它是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法。
工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能,以下是工厂接口的定义:

立即学习Java免费学习笔记(深入)”;

public interface Factory{ 
  public Product create(); 
} 
我们再来定义一个产品接口
public interface Product{} 
一下是实现了产品接口的产品类
public class Washer implements Product{ 
   public Washer(){ 
       System.out.println("洗衣机被制造了"); 
   } 
} 
 
public class Icebox implements Product{ 
   public Icebox(){ 
       System.out.println("冰箱被制造了"); 
   } 
} 
 
public class AirCondition implements Product{ 
   public Icebox(){ 
       System.out.println("空调被制造了"); 
   } 
} 
接下来,就是工厂方法的核心部分,也就是具体创建产品对象的具体工厂类,
//创建洗衣机的工厂 
public class CreateWasher implements Factory{ 
    public Product create(){ 
          return new Washer(); 
    } 
} 
 
//创建冰箱的工厂 
public class CreateIcebox implements Factory{ 
    public Product create(){ 
          return new Icebox(); 
    } 
} 
 
//创建空调的工厂 
public class CreateAirCondition implements Factory{ 
    public Product create(){ 
          return new AirCondition(); 
    } 
}


从上面创建产品对象的代码可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难.....

抽象工厂(Factory Method)
抽象工厂:意的意图在于创建一系列互相关联或互相依赖的对象。>
我自己觉得抽象工厂是在工厂方法的基础上引进了分类管理的概念....
工厂方法用来创建一个产品,它没有分类的概念,而抽象工厂则用于创建一系列产品,所以产品分类成了抽象工厂的重点,
我们继续用上面的例子来说明:
工厂生产的所有产品都用都用大写字母来标明它们的型号,比如冰箱,就有“冰箱-A",“冰箱-B",同样,其他的产品也都是遵守这个编号规则,于是就有了一下产品家族树

冰箱:

冰箱-A  

冰箱-B

麦艺画板(Max.art)
麦艺画板(Max.art)

AI工业设计平台,专注于汽车设计,线稿、渲染、3D建模全流程覆盖

下载

洗衣机:  

洗衣机-A  

洗衣机-B


我们可以为冰箱和洗衣机分别定义两个产品接口,以对他们进行分类,

//洗衣机接口 
public interface Washer{ 
} 
 
//冰箱接口 
public interface Icebox{ 
} 
接着,我们分别创建这两个接口的具体产品
//洗衣机-A 
public class WasherA implements Washer{ 
   public WasherA(){ 
       System.out.println("洗衣机-A被制造了"); 
   } 
} 
 
//洗衣机-B 
public class WasherB implements Washer{ 
   public WasherB(){ 
       System.out.println("洗衣机-B被制造了"); 
   } 
} 
 
//冰箱-A 
public class IceboxA implements Icebox{ 
   public IceboxA(){ 
       System.out.println("冰箱-A被制造了"); 
   } 
} 
 
//冰箱-B 
public class IceboxB implements Icebox{ 
   public IceboxB(){ 
       System.out.println("冰箱-B被制造了"); 
   } 
} 
到此,产品部分我们准备好了,接下来我们来处理工厂部分,我们先来定义工厂行为接口
public interface Factory{ 
       public Washer createWasher(); 
       public Icebox createIcebox(); 
}


接下来我创造具体的工厂类,我们根据上面产品的接口,把型号A的产品分为一类,由一个工厂来管理,把型号为B的产品有另一个工厂管理,根据这个分类,我们可以实现如下的两个具体工厂类

//创建型号为A的产品工厂 
public class FactoryA implements Factory{ 
       //创建洗衣机-A 
       public Washer createWasher(){ 
            return new WasherA(); 
       } 
 
       //创建冰箱-A 
       public Icebox createIcebox(){ 
            return new IceboxA(); 
       } 
} 
 
//创建型号为B的产品工厂 
public class FactoryB implements Factory{ 
       //创建洗衣机-B 
       public Washer createWasher(){ 
            return new WasherB(); 
       } 
 
       //创建冰箱-B 
       public Icebox createIcebox(){ 
            return new IceboxB(); 
       } 
}


这样,我们的抽象工厂就完成了。有上面可以看出,在运用上我觉得工厂方法和抽象工厂,都有自己的应用场景,并没有什么优劣之分,但在应用抽象工厂之前,要先对创建的对象进行系统的分类,这点很重要,好的产品分类规则能为具体工厂类的选择调用和以后的扩展提供清晰的思路.

更多Java设计模式—工厂设计模式相关文章请关注PHP中文网!

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

56

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

51

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

397

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

118

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

11

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3万人学习

ThinkPHP6.x API接口--十天技能课堂
ThinkPHP6.x API接口--十天技能课堂

共14课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号