问题提出

Java的工厂模式与现实生活中的工厂的模型是很相似的。工厂是用来做什么?当然是用来生成产品。因此在Java的工厂模式的关键点就是如何描述好产品和工厂这2个角色之间的关系。

下面来仔细描述一下不同的关系以及对应的设计模式

1)单一产品系,工厂只生产一种类型的产品

让我们简单构思一下简单的工厂生产模型,既然只有一个产品,那只需要一个车间就好了,一个车间分别生产三种不同种类的小汽车。好,下面看看简单工厂的设计模式。

//定义小汽车接口:ICar.java
public interface ICar {
}

public class TopCar implements ICar {
}

public class MidCar implements ICar {
}

public class LowCar implements ICar {
}

public class CarSimpleFactory {public static final String TOPTYPE = "toptype";public static final String MIDTYPE = "midtype";public static final String LOWTYPE = "lowtype";private CarSimpleFactory(){}public static ICar create(String mark){ICar obj = null;if(mark.equals(TOPTYPE)){obj = new TopCar();}else if(mark.equals(MIDTYPE)){obj = new MidCar();}else if(mark.equals(LOWTYPE)){obj = new LowCar();}return obj;}
}

简单工厂功能类编写步骤:

1.编写抽象产品接口

2.编写具体产品子类

3.编写工厂类。简单工厂类的特点,它是一个具体的类,非接口型抽象类。有一个重要的create()方法,并且用if...else或者switch开发创建所需产品。因为可以把这个简单工厂类实现成一个工具类,所以直接用静态方法就可以了,如有必要甚至可以把构造方法私有化。

下面考虑一种情形,工厂扩张啦!可以加工生产超级高档型的汽车。在上面的生产模式下要怎么修改呢?

1)新增ICar子类SuperCar

2)修改工厂类SimpleCarFactory中的create()方法,添加判断分支。

子类SuperCar的添加是必然的,然而能不能不用修改工厂类呢?

或者从另一个角度分析,在一个生产线上生产几种不同种类的产品,这样我们还需要对每个产品加以判断种类来分类。当然,假若只有2种种类要区分,这样当然没问题,但是若是有多个种类要区分呢?显然,不能在一条生产线上生产多种种类的产品!那意味着对于每一种种类我们都需要一条生产线。这就是所谓的工厂模式!

public abstract class AbstractFactory {public abstract ICar create();
}

public class LowFactory extends AbstractFactory {public ICar create(){return new LowCar();}
}

View Code

public class MidFactory extends AbstractFactory {public ICar create(){return new MidCar();}
}

View Code

public class TopFactory extends AbstractFactory {public ICar create(){return new TopCar();}
}

View Code

而观察代码,只要有ICar.java,AbstractFactory.java这两个文件,其他具体产品类,工厂类源文件没有,编译也能通过。

对于AbstractFactory,可以定义为抽象类,也可以定义为接口。这里的create()是抽象方法,没参数,表明在具体的子类工厂中创建某个具体产品。

工厂方法的主要特征是:当需求分析发生变化是,只需要增加和删除相应的类,而不是修改已有的类。例如添加超高档的小汽车,只需要增加SuperCar以及SuperFactory两个类即可。所以工厂方法更易于软件的二次开发以及维护。

当然啦,一个工厂很有可能不止生成一种产品。下面看看多产品系。

2)多产品系,特征相同

UML图与工厂模式基本没什么区别,这里就不再画了。

一般来说,简单工厂和工厂模式都是单产品系的,而对于上面这种架构,称之为抽象工厂。但从本质上来说,抽象工厂和工厂模式是统一的。这里就不再述说。

3)多产品系,部分特征相同

public abstract class AbstractFactory {/*** 多产品系,小汽车和公共汽车都有高,中档类型,小汽车有低档类型,而公共汽车没有*/
}

public abstract class AbstractFactory1 extends AbstractFactory {public abstract ICar createCar();   //产生小汽车对象public abstract IBus createBus();   //产生公共汽车对象
}

public abstract class AbstractFactory2 extends AbstractFactory {public abstract ICar createCar(); //产生小汽车对象
}

这里着重看看AbstractFactory,AbstractFactory1,AbstractFactory2.

1)具有相同特征的小汽车和公共汽车放在相同的工厂里面

2)该类也是抽象类,表明“特征是多个”。这里特征表示“高中低档”。

工厂模式大概就讲到这里,看到这里,相信很多人都有一种,工厂模式原来也不过如此。但是,个人觉得无论什么设计模式,看上去都似乎很好理解很容易。但是,当遇到问题需要自己分析设计的时候,就顿时没了头绪。

原因大概有2个,一是对这种设计模式还并不是十分熟悉和理解,二当然就是没有实践过。闲话不多说,下面让我们操刀实践一波。

例子:编写读文件功能。读取文本文件,包括GBK,UTF-8.编码下的文本文件,要求获得全文内容;读取图像文件,包括BMP,GIF,JPG文件,要求获得图像宽度,长度,每一点的三基色信息。

代码如下:

读取文本文件方法需要两个参数:文件名和编码方式;而读取图像文件需要一个参数:文件名。而根据题意,两种读取文件返回值类型有所差异。

如何用接口屏蔽方法参数个数,返回值类型的差异,是定义接口的关键。

public interface IRead<T> {//如何用接口屏蔽方法参数个数,返回值类型的差异,这是定义接口的关键
    T read(String ... in);
}

package factoryModel.explorer2;import java.io.File;
import java.io.FileInputStream;/*** Created by lenovo on 2017/4/17.*/
public class TextRead implements IRead<String> {    //读文本文件public String read(String ... in){              //可输入0或者多个参数String result = null;                       //result是结果串try{File file = new File(in[0]);            //in[0]代表文件名long len = file.length();FileInputStream input = new FileInputStream(in[0]);byte buf[] = new byte[(int)len];input.read(buf);result = new String(buf,in[1]);         //按照in[1]编码方式转化为可见字符串
            input.close();}catch (Exception ex){System.out.println(ex.getMessage());}return result;}
}

View Code

package factoryModel.explorer2;/*** Created by lenovo on 2017/4/17.*/
public class ImageInfo {private int width;      //图像宽度private int height;     //图像高度private int r[][];      //红色分量private int g[][];      //绿色分量private int b[][];      //蓝色分量public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int[][] getR() {return r;}public int[][] getG() {return g;}public int[][] getB() {return b;}public void setRGB(int rgb[]){r = new int [height][width];g = new int [height][width];b = new int [height][width];int pos = 0;for(int i=0;i<height;i++){pos = width*i;for(int j=0;j<width;j++){r[i][j] = (rgb[pos+j]&0xff0000)>>16;g[i][j] = (rgb[pos+j]&0x00ff00)>>8;b[i][j] = (rgb[pos+j]&0x0000ff);}}}}

View Code

package factoryModel.explorer2;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;/*** Created by lenovo on 2017/4/17.*/
public class ImageRead implements IRead<ImageInfo> {public ImageInfo read(String... in){BufferedImage bi = null;File f = new File(in[0]);try{bi = ImageIO.read(f);}catch (IOException ex){ex.printStackTrace();}int width = bi.getWidth();int height = bi.getHeight();int rgb[] = new int[width*height];bi.getRGB(0,0,width,height,rgb,width,height);       //将图像数据读到result缓存区ImageInfo imageInfo = new ImageInfo();imageInfo.setHeight(height);imageInfo.setWidth(width);return imageInfo;}
}

View Code

public abstract class AbstractFactory {  //定义抽象工厂public abstract IRead create();
}

public class TextFactory extends AbstractFactory {public IRead create(){return new TextRead();}
}

public class ImageFactory extends AbstractFactory {public IRead create(){return new ImageRead();}
}

对于上面抽象工厂类其实并不够完善,如何选择具体工厂类没有体现。解决方法有两种。一是像简单工厂那样添加选择分支。二是使用反射。

下面的代码是使用了反射技术

public abstract class AbstractFactory {public abstract IRead create();static AbstractFactory create(String className){AbstractFactory factory = null;try{Class c = Class.forName(className);factory = (AbstractFactory)c.newInstance();}catch (Exception ex){ex.printStackTrace();}return factory;}
}

运用反射技术,实现了更加灵活的自动工厂选择功能。当添加新具体工厂类的时候,不需要修改AbstractFactory类。

转载于:https://www.cnblogs.com/lateink/p/6725599.html

Java设计模式:工厂模式相关推荐

  1. Java设计模式-工厂模式(3)抽象工厂模式

    在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗.我们所见到的工厂 ...

  2. Java设计模式-工厂模式(2)工厂方法模式

    在Java设计模式-工厂模式(1)简单工厂模式 中我们介绍了简单工厂模式,提到了简单工厂模式违背了开闭原则,而"工厂方法模式"是对简单工厂模式的进一步抽象化,其好处是可以使系统在不 ...

  3. Java设计模式-工厂模式(1)简单工厂模式

    Java设计模式-工厂模式(1)简单工厂模式 一.前言 1)例子 2)类图关系 3)代码实现 二.简单工厂模式 2.1.概述: 2.2.类图关系: 2.3.代码修改: 2.4.优缺点 2.5.扩展-简 ...

  4. java设计模式工厂模式_Java中的工厂设计模式

    java设计模式工厂模式 Welcome to the Factory Design Pattern in Java tutorial. Factory Pattern is one of the C ...

  5. java设计模式工厂模式_Java中的复合设计模式

    java设计模式工厂模式 Composite pattern is one of the Structural design pattern. Composite design pattern is ...

  6. java设计模式工厂模式_Java中的桥梁设计模式

    java设计模式工厂模式 Today we will look into Bridge Design Pattern in java. When we have interface hierarchi ...

  7. java设计模式工厂模式_Java中的外观设计模式

    java设计模式工厂模式 Facade Design Pattern is one of the Structural design patterns (such as Adapter pattern ...

  8. java 工厂模式的写法_[java设计模式] 工厂模式解析

    什么是工厂模式? 我的总结是: 遵守软件设计中的开闭原则和依赖反转原则, 并且客户端只需通过参数来创造多个对象, 并且在创建过程中,创建对象的过程对客户端是透明的. 这种开发模式叫做工厂模式. 出现原 ...

  9. 10.Java设计模式 工厂模式,单例模式

    Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...

  10. 学习:java设计模式—工厂模式

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...

最新文章

  1. 贴吧html标签,html标签3(转载)
  2. Windows下将MySQL5.5升级为MySQL5.7
  3. c++ explicit(显式)关键字
  4. !JS实战之随机像素图
  5. tabula-java_Java FileSystems.getDefault方法代码示例
  6. UnitOfWork知多少
  7. 【kafka】InvalidReplicationFactorException: Replication factor: 1 larger than available brokers: 0
  8. 记一次线程池任务执行异常
  9. 一步一步使用标c编写跨平台图像处理库_让一个图像变成反向图像
  10. 牛逼哄哄的 RabbitMQ 到底有啥用?
  11. CAM350对比电路图方法
  12. Java、JSP基于Java的题库管理系统的设计与实现
  13. 2018.11.05._PYTHN_DJANGO_CLASS 144~CLASS147
  14. 原创:AIR202连接阿里云调试纪实1
  15. DSI3协议理论基础讲解
  16. 微信公众号发红包开发教程
  17. MachO 代码签名剖析
  18. dede织梦网站源码安装教程
  19. 创新实训(9)——SpringBoot整合solr
  20. 上海某软件公司电话面试分享

热门文章

  1. 啧啧,这种程序员……| 每日趣闻
  2. Xamarin 学习笔记 - 配置环境(Windows iOS)
  3. 让浏览器不记住表单元素输入过的内容
  4. 如果你在2018面试前端,那这篇文章最好看一看!
  5. golang的channel使用
  6. 从分布式数据库的CAP特性说起
  7. 当前标识(NT AUTHORITY\NETWORK SERVICE)没有对“的写访问权限。
  8. 残缺的完美 送给飘
  9. poj1256(贪心+并查集)
  10. linux c/c++ GDB教程详解