【java设计模式】(4)---工厂模式(案例解析)
设计模式之工厂模式
工厂模式分三种:简单工厂模式(也叫静态工厂模式),工厂方法模式(也叫多形性工厂),抽象工厂模式(也叫工具箱)下面会一一举例。
一、概念
1、什么是工厂模式
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。工厂模式关心的是最终产出(创建)的对象, 而不关心创建的过程。
2、工厂模式的优点
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。同时会给你系统带来更大的可扩展性和尽量少的修改量。(下面第三点会举例说明)
3、什么情况使用工厂模式
这也是具体的说明工厂模式优点。我个人认为在任何需要生成复杂对象的地方,都可以考虑使用工厂模式。
我们以线程池的举例。
ThreadPoolExecutor类的四个构造方法。
public class ThreadPoolExecutor extends AbstractExecutorService {
.....
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
...
}
我们可以看到线程池的构造函数要传入的参数很多参数才能创建对象,但是其实这里很多参数尤其是后面3个参数基本上用默认值,而不需每次传入。
那看下线程池的工厂模式(都是使用静态工厂模式创建对象)。
Executors.newCachedThreadPool(); //创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE
Executors.newSingleThreadExecutor(); //创建容量为1的缓冲池
Executors.newFixedThreadPool(int); //创建固定容量大小的缓冲池
下面是这三个静态方法的具体实现:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
是不是都已经传入一些默认值,这让我们无需再思考在构造函数中应该传入什么值而苦恼,而直接通过工厂模式获取一个对象。
二、简单工厂模式
学习简单工厂模式的时候我用的是一个与人类有相关的例子。人类在世界分为男人和女人,首先定义一个NvWa(女娲)产品的抽象接口
/**
* 产品的抽象接口 女娲
*/
public interface NvWa { public void say();
}
然后定义男人和女人,同样都有说话的方法。
/**
* man 男人
*/
public class Man implements NvWa { @Override
public void say() {
System.out.println("男人");
} }
/**女人
*/
public class Women implements NvWa { @Override
public void say() {
System.out.println("女人");
}
}
最后写一个工厂类,用来创造男人和女人。第一种方式是使用逻辑判断的方式实现的。
/**
* 简单工厂
*/
public class SampleFactory {
public static NvWa makeNvWa(String type){
if(type.equals("man")){
NvWa man = new Man();
return man;
}else if(type.equals("wommen")){
NvWa women = new Women();
return women;
}else{
System.out.println("生产不出来");
return null;
}
}
}
第二方式是使用java的放射实现的(推荐)
/**
* 简单工厂放射实现
*/
public class SampleFactory1 {
public static NvWa makeNvWa(Class c){
NvWa nvwa = null;
try {
nvwa= (NvWa) Class.forName(c.getName()).newInstance();
} catch (ClassNotFoundException e) {
System.out.println("类不存在");
e.printStackTrace();
}
return nvwa;
}
}
反射测试类代码
package com.roc.factory;
/**
* 简单工厂测试*/
public class Client {
public static void main(String[] args) {
NvWa man = SampleFactory1.makeNvWa(Man.class);
man.say();
NvWa women = SampleFactory1.makeNvWa(Women.class);
women.say();
}
}
总结下:
简单工厂模式实质:是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
简单工厂模式缺点:严重违反开闭原则,因为这个时候如果女王要造人妖的话,那肯定要修改工厂的方法,这就违反了开闭原则:修改关闭,对扩展开放。
三、工厂方法模式
在简单的工厂模式里,我们创建了一个类似工具的类来创建相应的具体类对象。正因为其太过简单,不符合开闭原则。
工厂方法模式就是把简单工厂中具体的工厂类,划分成两层:抽象工厂层+具体的工厂子类层。(就是把具体抽象类多添加一层)
网上盗一张图(非常完美的图)

具体例子(把上面的具体实现工厂拆分)
NvWaFactory(造人工厂)
public abstract class NvWaFactory {
public abstract NvWacreate();
}
Man工厂(具体工厂子类)
public class ManFactory extends NvWaFactory {
@Override
public NvWa create() {
return new Man();
}
}
WoMen工厂(具体工厂子类)
public class WomenFactory extends NvWaFactory {
@Override
public NvWa create() {
return new Women();
}
}
测试类
/**
* 工厂方法模式:
*/
NvWaFactory factory1 = new ManFactory();
Man man= factory1.create();
man.say();
工厂方法与简单工厂的区别:
可以看出,普通工厂模式特点:不仅仅做出来的产品要抽象, 工厂也应该需要抽象。
工厂方法的好处就是更拥抱变化。比如现在在需要造人妖你只要在写个具体的人妖工厂,而不用像简单工厂去修改makeNvWa方法,所以工厂方法模式不会违反开闭原则。
四、抽象工厂模式
从上面的工厂方法中的结构图中,我们可以看到其中的具体工厂A和B是两个完全独立的。两者除了都是抽象工厂的子类,没有任何其他的交集。
可以理解工厂方法模式都是单产品系的。抽象工厂是多产品系 。
再盗一张图,这张图解释非常到位,下面例子如果没理解,那么再仔细思考这张图

我们修改下上面的工厂方法中的总工厂
public abstract class AbstractFactory {
/**
* 生产人类
*/
public abstract NvWa createNvWa();
/**
* 生产汽车(这个类就不具体些了,理解就好)
*/
public abstract Car createCar();
}
具体工厂1
/*具体工厂1:这里生产男人和宝马车
*/
public class Factory1 extends AbstractFactory { @Override
public NvWa createNvWa() {
return new Man();
} @Override
public Car createCar() {
return new Bmw();
}
}
具体工厂2
/*具体工厂2:这里生产女人和奔驰车
*/
public class Factory2 extends AbstractFactory { @Override
public NvWa createNvWa() {
return new Women();
} @Override
public Car createCar() {
return new Bc();
}
}
功能测试
有了这些东西,那么我们就来好好生产一些产品吧.
public class FactoryTest {
public static void main(String[] args) {
//工厂1生产男人和宝马
AbstractFactory factory1 = new Factory1();
Man man = factory1.createNvWa();
Bmw bmw = factory1.createCar();
//工厂2生产女人和奔驰
AbstractFactory factory2 = new Factory2();
Women women = factory2.createNvWa();
Bc bc = factory2.createCar();
}
}
个人总结下:
简单工厂模式它的优点就是简单,而且违背了开闭原则。不过静态工厂模式在实际中用到比较多。工厂方法模式修复了开闭原则,但它也有一个缺点每次新增一个具体产品类,也要同时新增一个具体工厂类,会造成类太多。
工厂方法模式比抽象工厂也会用的多,因为抽象工厂结构不像工厂方法那样清晰。
想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。中校【6】
【java设计模式】(4)---工厂模式(案例解析)的更多相关文章
- 浅析JAVA设计模式之工厂模式(一)
1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...
- Java设计模式之工厂模式(Factory模式)介绍(转载)
原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...
- Java 设计模式之工厂模式(二)
原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...
- 浅析JAVA设计模式之工厂模式(二)
1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...
- java设计模式2————工厂模式
1.工厂模式介绍: 1.1.实现了创建者与调用者的分离 1.2.详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 1.3.所遵循的OOP原则: 开闭原则:对扩展开放,对修改关闭 依赖倒转原则:面向 ...
- java 设计模式之工厂模式与反射的结合
工厂模式: /** * @author Rollen-Holt 设计模式之 工厂模式 */ interface fruit{ public abstract void eat(); } ...
- JAVA设计模式--抽象工厂模式
抽象工厂设计模式 1.系统中有多个产品族,而系统一次只可能消费其中一族产品2.同属于同一个产品族的产品以其使用.来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):抽象工厂角色: 这是工厂方法模式的 ...
- Java设计模式之-----工厂模式(简单工厂,抽象工厂)
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
- Java设计模式之工厂模式(简单工厂模式+工厂方法模式)
摘自http://blog.csdn.net/jason0539/article/details/23020989 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是 ...
- java设计模式之一工厂模式
简单工厂模式是java设计模式中最简单的设计模式之一: 工厂模式是最常用的设计模式之一. 工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模 ...
随机推荐
- php八种常用函数
八种常用的数学函数: ① abs(x):求绝对值 ② ceil(x),floor(x):向上/下取最接近的整数 ③ cos(x),sin(x),tan(x):三角函数 ④ min(),max( ...
- Alpha冲刺(2/10)——2019.4.24
作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Alpha冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 ...
- Hibernate: '\xE6\x9D\x8E\xE5\x9B\x9B' for column 'cust_name' at row 1 解决
新建Hibernate,出现异常 20:11:03,117 WARN SqlExceptionHelper:137 - SQL Error: 1366, SQLState: HY000 20:11:0 ...
- 1.3 正则表达式和python语言-1.3.6匹配多个字符串
1.3.6 匹配多个字符串(2018-05-08) 我们在正则表达式 bat|bet|bit 中使用了择一匹配(|)符号.如下为在 Python中使用正则表达式的方法. import re #bat| ...
- H5测试点总结-UI测试、功能测试、兼容性测试、体验相关(弱网、资源、手机操作等)、安全性测试、性能测试
一.概述 1.1 什么是H5 H5 即 HTML5,是最新的 Web 端开发语言版本,现如今,大多数手机 APP 页面会用 H5 实现,包括 PC Web 站点也会用它开发实现.所以 Web 的通用测 ...
- imagecreatefrombmp、imagebmp php处理bmp文件
/*格式组成典型的BMP图像文件由四部分组成: 1:位图头文件数据结构,它包含BMP图像文件的类型.显示内容等信息: 2:位图信息数据结构,它包含有BMP图像的宽.高.压缩方法,以及定义颜色等信息: ...
- Charles抓包软件简介
Charles简介: Charles是一款抓包神器,因为他是基于 java 开发的,所以跨平台,Mac.Linux.Window下都是可以使用的,确保安装之前已经安装了JDK.Charles官网地址: ...
- django介绍及路由系统
第一:Python的web框架介绍 Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引 ...
- mysql5.7忽略大小写问题
mysql5.7忽略大小写问题 1.1 前言 新安装mysql5.7版本后,linux环境下默认是大小写敏感的. 1.2 忽略大小写敏感步骤 进入mysql配置文件: vi /et ...
- ABP入门系列(1)——通过模板创建MAP版本项目
ABP入门系列目录--学习Abp框架之实操演练 一.从官网创建模板项目 进入官网下载模板项目 依次按下图选择: 输入验证码开始下载 下载提示: 二.启动项目 使用VS2015打开项目,还原Nuget包 ...