工厂模式的适用场景
工厂模式适用的一些场景(不仅限于以下场景):
1. 对象的创建过程/实例化准备工作很复杂,需要初始化很多参数、查询数据库等。
2.类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变。
工厂模式的设计原则
有定义一个创建对象的接口,让子类做具体的实现,而对象的创建统一交由工厂去生产,有良好的封装性,既做到了解耦,也保证了最少知识原则。
任何的设计模式都是用来解决某一些特定场景问题的一种思想,如果在开发过程中遇到某一些问题,可以回顾自己脑海中的所有知识,是不是可以使用设计模式去解决,当然自己也可以不用设计模式,用其他的方式也是可以的,只要能解决就可以。
案例实战
编写读文件功能。读取文件,包括编码(GBK,UTF-8,UNIONCODE)的文本文件,要求获取文本内容。读取图像文件(BMP,GIF,JPG),要求获取图像宽度、高度、长度、以及每一点的RGB基色信息。
首先我们可以写出一个基本的工厂类模式,如下所示,生成对应的读取总接口,以及对应的文本和图像抽象类,及对应的子列,对应子类的工厂方法,实现要求
一、根据语意画出层次功能图 和UML图
层次功能图
读取文件的UML图
二、定义读取文本、图像的接泛型口:
package com.lzhsite.technology.designPattern.factory; /** * 类描述:读文本、图像文件接口 * */ public interface IRead<T> { /** * * 方法说明:根据传入的文件名读取文件 * * Author: Jing Create Date: Dec 18, 2014 4:15:27 PM * * @param in * @return * @return T */ T read(String... in); }
三、定义读取图像和文件的具体实现类
package com.lzhsite.technology.designPattern.factory; import java.io.File; import java.io.FileInputStream; /** * 类描述:文本读取 * */ public class TextRead implements IRead<String> { public String read(String... in) { String result = null; try{ File file = new File(in[0]); long len = file.length();//文件长度 FileInputStream fis = new FileInputStream(in[0]);//in[0] 存储文件名称 byte buf[] = new byte[(int)len]; fis.read(buf); result = new String(buf, in[1]);//in[1]存储编码方式 fis.close(); }catch(Exception e){ System.out.println(e.getMessage()); } return result; } }
package com.lzhsite.technology.designPattern.factory; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; /** * 类描述:图像文件读取 * */ public class ImageRead implements IRead<ImageInfo>{ public ImageInfo read(String... in) { BufferedImage bi = null; File f = new File(in[0]);//in[0]存储文件名 try { bi = ImageIO.read(f); } catch (IOException e) { e.printStackTrace(); } int width = bi.getWidth(); int height = bi.getHeight(); int rgb[] = new int[width * height]; bi.getRGB(0, 0, width, height, rgb, width, height); ImageInfo info = new ImageInfo(); info.setWidth(width); info.setHeight(height); info.setRGB(rgb); return info; } }
四、定义抽象工厂
package com.lzhsite.technology.designPattern.factory; /** * 类描述:抽象工厂 */ public abstract class AbstractFactory { /** * * 方法说明:获取对应的读取对象 * * @return * @return IRead */ @SuppressWarnings("unchecked") public abstract IRead create(); /** * * 方法说明:使用反射,根据掺入的类名生成对应的对象 * * @param className * @return * @return AbstractFactory */ static AbstractFactory create(Class clazz){ AbstractFactory factory = null; try{ factory = (AbstractFactory) clazz.newInstance(); }catch(Exception e){ e.printStackTrace(); } return factory; } }
五、定义具体工厂
package com.lzhsite.technology.designPattern.factory; /** * 类描述:图像读取 * */ public class TextFactory extends AbstractFactory { @SuppressWarnings("unchecked") @Override public IRead create() { return new TextRead(); } }
package com.lzhsite.technology.designPattern.factory; /** * 类描述:图像读取 * */ public class ImageFactory extends AbstractFactory { @SuppressWarnings("unchecked") @Override public IRead create() { return new ImageRead(); } }
六、测试代码
package com.lzhsite.technology.designPattern.factory; public class ReadTest{ public static void main(String[] args) { TextFactory textFactory = (TextFactory) AbstractFactory.create(TextFactory.class); IRead iRead = textFactory.create(); iRead.read("test.txt","utf-8"); } }