关闭

Java设计模式2:简单工厂模式

标签: 工厂模式java设计模式
208人阅读 评论(0) 收藏 举报
分类:

简单工厂模式

简单工厂模式是类的创建模式,又叫做静态工厂方法模式。简单工厂模式由一个工厂对象决定生产出哪一种产品类的实例。

 

为什么要使用简单工厂模式

原因很简单:解耦。

A对象如果要调用B对象,最简单的做法就是直接new一个B出来。这么做有一个问题,假如C类和B类实现了同一个接口/继承自同一个类,系统需要把B类修改成C类,程序不得不重写A类代码。如果程序中有100个地方new了B对象,那么就要修改100处。

这就是典型的代码耦合度太高导致的"牵一发动全身"。所以,有一个办法就是写一个工厂IFactory,A与IFactory耦合,修改一下,让所有的类都实现C接口并且IFactory生产出C的实例就可以了。

 

简单工厂模式示例

以水果为例:

public interface Fruit
{
    void grow();// 生长
    void harveset(); // 收货
    void plant();// 种植
}

有两个子类苹果和葡萄:

复制代码
public class Apple implements Fruit
{
    public void grow()
    {
        System.out.println("Apple.grow()");
    }

    public void harveset()
    {
        System.out.println("Apple.harveset()");
    }

    public void plant()
    {
        System.out.println("Apple.plant()");
    }
}
复制代码
复制代码
public class Grape implements Fruit
{
    public void grow()
    {
        System.out.println("Grape.grow()");
    }

    public void harveset()
    {
        System.out.println("Grape.harveset()");
    }

    public void plant()
    {
        System.out.println("Grape.plant()");
    }
}
复制代码

有一个园丁,专门负责生产出各种水果:

复制代码
public class Gardener
{
    public static Fruit getFruit(String fruit)
    {
        if ("apple".equalsIgnoreCase(fruit))
        {
            return new Apple();
        }
        else if ("grape".equalsIgnoreCase(fruit))
        {
            return new Grape();
        }
        else
        {
            return null;
        }
    }
}
复制代码

想要什么水果就问园丁拿就好了:

复制代码
public static void main(String[] args)
{
    Fruit fruit0 = Gardener.getFruit("APPLE");
    fruit0.grow();
    Fruit fruit1 = Gardener.getFruit("GRAPE");
    fruit1.harveset();
}
复制代码

程序这么写优点就出来了:

1、用户不自己去生产产品,只需要负责去拿自己需要的东西就好了,这样用户-->产品之间的耦合度就降低了

2、代码模块职责更明确了,有专门消费的模块、有专门生产的模块

 

改进

上面的代码虽然实现了用户-->产品之间的分离,但还是有一个问题,工厂并不知道有多少种产品,所以每一次新增产品的时候,都需要新增else if分支,这样是不是不便呢?所以我们又想了一个办法,就是反射,园丁可以这么修改:

复制代码
public class Gardener
{
    public static Fruit getFruit(String fruitPath) throws Exception
    {
        Class<?> c = Class.forName(fruitPath);
        return (Fruit)c.newInstance();       
    }
}
复制代码

调用的地方可以写成:

复制代码
public static void main(String[] args) throws Exception
{
    Fruit fruit0 = Gardener.getFruit("com.xrq.simplefactory.Apple");
    fruit0.grow();
    Fruit fruit1 = Gardener.getFruit("com.xrq.simplefactory.Grape");
    fruit1.harveset();
}
复制代码

当然,这么写其实也有一点点问题,假如有一天我的项目想进行一个重构,重整类路径,包路径,比方说生产Apple的地方有100处,岂不是要修改100处?当然不用,有以下三种方法推荐:

1、写一个接口FruitPath,里面定义常量:

public interface FruitPath
{
    public final static String apple = "com.xrq.simplefactory.Apple";
    public final static String grape = "com.xrq.simplefactory.Grape";
}

2、写一个Fruit.properties文件,里面定义水果和类路径的对应关系:

Apple=com.xrq.simplefactory.Apple
Grape=com.xrq.simplefactory.Grape

3、写一个Fruit.xml文件,里面定义水果和类路径的对应关系:

<apple>com.xrq.simplefactory.Apple</apple>
<grape>com.xrq.simplefactory.Grape</grape>

第一种方式不说了,第二种方式.properties可以用Java自带的Properties类来解析,第三种方式.xml可以用DOM4J来解析。这样, 假设我以后要修改水果的路径,修改一个文件就可以了。

从设计模式的角度讲,这么修改也有很大的优点。现在不管我新增还是删除水果,园丁(类工厂)都不用变了,只需要告诉工厂我需要哪种水果就够了,工厂自然会给调用者返回。这种写法,也是Spring的基础。

最后说一点,希望大家明白,简单工厂模式或者说工厂模式的关注点并不在于在工厂中是如何生产出来需要的类的,而在于将创建产品与消费产品分离。前面使用过if...else if...else、反射,除了这些方法,还可以有别的方法可以创建产品,比如传入一个具体产品的标识,根据这个标识去数据库里面查询。

 

简单工厂模式在Java中的应用及解读

以后每一篇文章尽可能地介绍设计模式在Java中的应用,因为我认为不是每种设计模式开发者都有机会可以用到,但是能在原有代码中敏锐地看出这是一种什么设计模式,至少能说明对这种设计模式是理解了。这里讲一下JDK中的简单工厂模式。

JDK中的简单工厂模式有很多应用,比较典型的比如线程池,具体可以参见Java多线程18:线程池。我们使用线程池的时候,可以使用ThreadPoolExecutor,根据自己的喜好传入corePoolSize、maximumPoolSize、keepAliveTimem、unit、workQueue、threadFactory、handler这几个参数,new出一个指定的ThreadPoolExecutor出来。

JDK给开发者提供了Executors这个类,可以让用户产生ThreadPoolExecutor和使用ThreadPoolExecutor分离开,比如可以让Executors提供一个单线程的线程池Executors.newSingleThreadExecutor()、让Executors提供一个无界线程池Executors.newCachedThreadPool()等,这样,开发者可以不用关心线程池是如何去实现的,直接使用Executors方法提供给开发者的ThreadPoolExecutor就可以了。

 

工厂模式的优缺点

优点:

1、简单优化了软件体系结构,明确了各自功能模块的职责和权利

2、通过工厂类,外界不需要直接创建具体产品对象,只需要负责消费,不需要关心内部如何创建对象

缺点:

1、改进前的简单工厂模式全部创建逻辑都集中在一个工厂类中,能创建的类只能是考虑到的,如果需要添加新的类,就必须改变工厂类了

2、改进前的简单工厂模式随着具体产品的不断增多,可能会出现共产类根据不同条件创建不同实例的需求,这种对条件的判断和对具体产品类型的判断交错在一起,很难避免功能模块的蔓延,对系统的维护和扩展不利

3、改进后的简单工厂模式主要是使用反射效率会低一些

0
0
查看评论

java设计模式学习笔记之计算器中的简单工厂模式

java设计模式学习笔记之计算器中的简单工厂模式 最近在重温设计模式,偶然看到程杰的《大话设计模式》写的非常不错、通俗易懂,之后的一系列都是学习的笔记,仅此记录。 一、情景回放:某校大二软件工程专业班的《Java程序设计》课上,老师给大伙出了一个题目:用java实现一个简单的计算器功能(用
  • qq137722697
  • qq137722697
  • 2016-11-30 21:56
  • 2266

设计模式——简单工厂(又叫静态工厂方法,不属于GOF23中设计模式)

简单工厂模式属于类的创新型模式,又叫静态工厂方法模式,是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 —————————————————————————————————————————————————————————————— 角色 工厂角色:简单工厂模式的核心,它负...
  • sunqingzhong44
  • sunqingzhong44
  • 2016-07-01 10:01
  • 236

简单工厂设计模式的好处

简单工厂:单独的,创建对象,返回对象。 在一个方法中创建好对象,调用此方法即根据传入参数可获得到不同需求的对象,我曾纳闷为什么要单独创建对象,为什么不直接new对象使用? 唉,好处就在这儿,咋想想方法吧,为什么要设计方法? 方法是一片代码的封装,集合,方法中写好一片代码,你需要此方法的功能时...
  • Java_Dmz
  • Java_Dmz
  • 2017-09-02 13:58
  • 213

C++ 设计模式之——简单工厂模式(SimpleFactoryPattern)

简单工厂模式   简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模...
  • nie2314550441
  • nie2314550441
  • 2016-02-18 17:40
  • 414

java设计模式 实验一-简单工厂模式

**简单工厂模式** 班级:软件工程1班 姓名:张雨 学号:2014416558 一、实验目的: 简单工厂设计模式应用 二、实验内容: 题目(一): 使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Wom...
  • a1120575649
  • a1120575649
  • 2016-09-23 23:20
  • 774

设计模式(四)简单工厂模式

简单工厂模式属于创建型模式又叫做静态工厂方法模式,是由一个工厂对象决定创建出哪一种产品类的实例。
  • itachi85
  • itachi85
  • 2016-02-12 17:19
  • 8256

简单工厂模式的UML类图与源码实现

原文:http://hlzhou.iteye.com/blog/551492 源码:Operation类 Java代码   package Operation;     ...
  • lan861698789
  • lan861698789
  • 2014-02-28 21:03
  • 2347

C语言实现设计模式之简单工厂模式(无内存泄露)

最近工作之余研究一下设计模式细节方面的东西,很多经典的东西需要一遍遍去读、去理解,设计模式就是这样的程序设计的经典之作。 我一直坚信学习是把书读薄,又把书读厚的过程,最终达到游刃有余。 言归正传,接下来是研究设计模式自己亲手写下的一段代码,看见网上也有很多人发了关于使用简单工厂实现计算的代码,可是都...
  • mayuming77
  • mayuming77
  • 2014-09-06 15:46
  • 478

Android重拾设计模式系列——简单工厂模式

定义及实质 定义 提供一个创建对象实例的功能(接口),而客户调用时无须关心实现过程。属于创建型模式。 实质 选择实现。 模式图解简单工厂模式UML图 解释: 从上图可以看出: 1. Factory依赖了Api接口和两个接口的实现类; 2. 而Client依赖Factory和Api接口; ...
  • qq_31370269
  • qq_31370269
  • 2016-11-10 16:50
  • 1880

python实现常见的设计模式-简单工厂模式

《大话设计模式》这本书中各种设计模式的python代码实现。简单工厂模式的UML图 工厂模式在很多场景都可以应用,运用类的继承、多态等强大的特点可以有效减少代码冗余,提高代码的高可复用性。#! /usr/bin/env python # -*- coding:utf-8 -*-"&quo...
  • fly9006
  • fly9006
  • 2017-02-19 21:13
  • 359
    个人资料
    • 访问:46327次
    • 积分:833
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:112篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论