【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() 工厂模 ...
随机推荐
- js浮点数的加减乘除
;(function(root, factory) { // Support AMD if (typeof define === 'function' && define.amd) { ...
- Centos给文件设置了777权限仍不能访问解决方案
Centos给文件设置了777权限仍不能访问: 开启了SELinux导致 1.查看SELinux状态:/usr/sbin/sestatus -v ##如果SELinux status参数为enable ...
- Core Location实现定位
2013/4/22记录: 注意:如非必要,不应该多次轮询位置信息i 使用时,可根据需要制定精度,通过仔细制定所需的绝对最低精度级别,可以纺织不必要的电池消耗. 导入:CoreLocation.f ...
- #工具 Intellij IDEA中自定义的Maven Archetype管理
背景,手贱在输入自定义的 archetype时后面多输入了一个空格 解决:自定义的Archetype 会保存在Windows下面的文件中 C:\Users\<user>\.IntelliJ ...
- 大数据计算框架Hadoop, Spark和MPI
转自:https://www.cnblogs.com/reed/p/7730338.html 今天做题,其中一道是 请简要描述一下Hadoop, Spark, MPI三种计算框架的特点以及分别适用于什 ...
- CommonsChunkPlugin
CommonsChunk 插件的作用就是提取代码中的公共代码,然后将公共模块打包到一个独立的文件中,以便在其它的入口和模块中使用,原理就是把多个入口共同的依赖都给定义成一个新入口 多种打包情况: 单一 ...
- [LeetCode] Reordered Power of 2 重新排序为2的倍数
Starting with a positive integer N, we reorder the digits in any order (including the original order ...
- 用简单的代码让一组静态图片变成gif动画
比如这组图片: 变成这样的gif动画: 是不是很神奇.... 先看html .样式.很简单,一个div,然后引入图片. <!DOCTYPE html> <html ...
- Katalon Studio之swagger中的API导入
约束条件: swagger中一定要在注解@ApiOperation中设置nickname的唯一值,例如: @ApiOperation(value="新增用户",notes=&quo ...
- Live2D插件--漂浮的二次元小姐姐
这个插件找了很久,都没找到,今天偶然翻到一个小哥的博客发现了这个,果断偷走. 教程转自简书:https://www.jianshu.com/p/1cedcf183633 还有这些,你可能有用 修改位置 ...