【java设计模式】(4)---工厂模式(案例解析)

设计模式之工厂模式

工厂模式分三种:简单工厂模式(也叫静态工厂模式),工厂方法模式(也叫多形性工厂),抽象工厂模式(也叫工具箱)下面会一一举例。java

1、概念

一、什么是工厂模式

     这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式工厂模式关心的是最终产出(建立)的对象, 而不关心建立的过程设计模式

二、工厂模式的优势

工厂模式主要是为建立对象提供过渡接口,以便将建立对象的具体过程屏蔽隔离起来,达到提升灵活性的目的。同时会给你系统带来更大的可扩展性和尽可能少的修改量。(下面第三点会举例说明)ide

三、什么状况使用工厂模式

这也是具体的说明工厂模式优势。我我的认为在任何须要生成复杂对象的地方,均可以考虑使用工厂模式。函数

咱们以线程池的举例。工具

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个参数基本上用默认值,而不需每次传入。测试

那看下线程池的工厂模式(都是使用静态工厂模式建立对象)。spa

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>()); }

是否是都已经传入一些默认值,这让咱们无需再思考在构造函数中应该传入什么值而苦恼,而直接经过工厂模式获取一个对象。设计

 

2、简单工厂模式

学习简单工厂模式的时候我用的是一个与人类有相关的例子。人类在世界分为男人和女人,首先定义一个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(); } }

总结下:

简单工厂模式实质:是由一个工厂类根据传入的参数,动态决定应该建立哪个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的建立目标,全部建立的对象都是充当这个角色的某个具体类的实例。

简单工厂模式缺点:严重违反开闭原则,由于这个时候若是女王要造人妖的话,那确定要修改工厂的方法,这就违反了开闭原则:修改关闭,对扩展开放。

 

3、工厂方法模式

在简单的工厂模式里,咱们建立了一个相似工具的类来建立相应的具体类对象。正由于其太过简单,不符合开闭原则。

工厂方法模式就是把简单工厂中具体的工厂类,划分红两层:抽象工厂层+具体的工厂子类层。(就是把具体抽象类多添加一层)

网上盗一张图(很是完美的图)

具体例子(把上面的具体实现工厂拆分)

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方法,因此工厂方法模式不会违反开闭原则

 

4、抽象工厂模式

从上面的工厂方法中的结构图中,咱们能够看到其中的具体工厂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】   

相关文章
相关标签/搜索