今天来说说工厂模式,好记性不如烂博客啊!以例子来说,是最好理解的。
假如说,你要制作一个APP,类似脸萌的APP。它提供好多好多的眼睛,好多好多的发型可供选择。通常,我们的日常生活中要产生大量的类似对象,都是交由工厂来批量生产。那么,世界上的理论总是惊人的相似,正如我们模拟人的大脑视觉运作机制,而产生了神经网络算法一样。把现实世界的工厂搬到代码设计中也是可行的,可就是——工厂模式
从字面来看,得其意二三分。到底什么是工厂模式呢?
实例化对象,用工厂方法代替new操作
意图:
定义一个借口来创建对象,但是让子类来决定哪些类需要被实例化,工厂方法把实例化的工作推迟到子类中去实现。
适合的场所:
有一组类似的对象需要创建
在编码时不能预见需要创建哪种类的实例
系统需要考虑扩展性,不应该以来于产品类实例如何被创建、组合和表达的细节(低耦合)
如下图,客户要请求一个物件,我们就调用工厂接口来实例化一个产品
来一个小小的实例理解一下
以脸萌中的发型实现为例,我们有左偏分发型和右偏分发型,看例子:
一个产生头发的借口,以及实现类
/** * 发型接口 * @author Administrator */ public interface HairInterface { /** * 画图 */ public void draw(); }
/** * 右偏分发型 * @author Administrator * */ public class RightHair implements HairInterface { @Override public void draw() { // TODO Auto-generated method stub System.out.println("-----------------右偏分发型-------------------"); } }
/** * 左偏分发型 * @author Administrator * */ public class LeftHair implements HairInterface { @Override public void draw() { // TODO Auto-generated method stub System.out.println("-----------------左偏分发型-------------------"); } }
public class SunnyTest { public static void main(String[] args){ // HairInterface left = new LeftHair(); // left.draw(); } }
得到:
-----------------左偏分发型-------------------
这样呢!也就算是实现了,但是还是存在着问题
1.每添加一个发型就要添加一个新的类来实现发行接口,不利于代码维护和管理
2.在客户端要显式调用draw方法
那么怎么办呢??这不工厂还没起作用嘛!新建一个HairFactory来统一生产发型,那么也就解决了上面的第二个问题。实现如下:
import java.util.Map; /** * 发型工厂 * @author Administrator */ public class HairFactory { /** * 根据类型来创建对象 * @param key ;类型关键字 * @return */ public HairInterface getHair(String key){ if("left".equals(key)){ return new LeftHair(); }else if("right".equals(key)){ return new RightHair(); } return null; } }
Test.java中
HairFactory factory = new HairFactory(); HairInterface right = factory.getHair("right"); right.draw();
得到:
-----------------右偏分发型-------------------
那么现在我们又发现,我们每多一种类型的发型,就要在getHair方法中添加一个if分支,这样也是特别不利于管理的,那么该怎么办呢?
JAVA中有一种类的反射机制(不详述),应用类的反射,根据类的名称来创建对象。
在HairFactory中:
/** * 根据类的名称来生产对象 * @param className * @return */ public HairInterface getHairByClass(String className){ try { HairInterface hair = (HairInterface) Class.forName(className).newInstance(); return hair; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
此时,Test.java类中传入全路径
HairInterface left =factory.getHairByClass("com.sunny.project.LeftHair"); left.draw();
得到:
-----------------左偏分发型-------------------
我们这么做就可以根据类名直接创建实例,利于代码的管理
但精益求精的路上,总是看不爽这么长的参数,有没有办法可以让这个参数简单明了呢?
那自然是有的........
JAVA中有一个属性文件(.properties),以key,value形式存储数据
我们新建一个type.properties
left=com.sunny.project.LeftHair right=com.sunny.project.RightHair
有了这个文件,要怎么来使用呢?这里就涉及到了文件操作,读取该文件找到对应关系
Java中有一个Properties类,用来操作properties文件的
import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * properties文件的读取工具 * @author Administrator * */ public class PropertiesReader { public Map<String, String> getProperties() { Properties props = new Properties(); Map<String, String> map = new HashMap<String, String>(); try { InputStream in = getClass().getResourceAsStream("type.properties"); props.load(in); Enumeration en = props.propertyNames(); while (en.hasMoreElements()) { String key = (String) en.nextElement(); String property = props.getProperty(key); map.put(key, property); // System.out.println(key + " " + property); } } catch (Exception e) { e.printStackTrace(); } return map; } }
这个时候我们的getHair方法有需要升级了
/** * 根据类的名称来生产对象 * @param className * @return */ public HairInterface getHairByClassKey(String key){ try { Map<String, String> map = new PropertiesReader().getProperties(); HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance(); return hair; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
此时客户端实现为
HairInterface hair = factory.getHairByClassKey("right"); hair.draw();
得到:
-----------------右偏分发型-------------------
我们现在想要增加一个中分发型,要怎么办呢??
新建一个InHair类实现HairInterface
/** * 中分发型 * @author Administrator * */ public class InHair implements HairInterface { @Override public void draw() { // TODO Auto-generated method stub System.out.println("-----------------中分发型-------------------"); } }
然后还需要做什么呢??是不是在propertied文件中添加对应关系
in=com.sunny.project.InHair
测试:
HairInterface hair = factory.getHairByClassKey("in"); hair.draw();
得到:
-----------------中分发型-------------------
这个工厂模式到这里就完全实现了,我们添加新的发型不需要修改HairFactory,只需要添加对应关系和相应的实现类。
Software entities should be open for extension,but closed for modification——Bertrand Meyer
对扩展开放,对修改关闭——“开闭原则”
参考资料:http://www.imooc.com/video/5316
相关推荐
这个是http://blog.csdn.net/dawanganban/article/details/9884681博客中java设计模式的源代码。下载前请先看《设计模式——工厂模式在开发中的应用》一文。
这个是http://blog.csdn.net/dawanganban/article/details/9877593博客中java设计模式的源代码。下载前请先看《设计模式——工厂方法模式》一文。
设计模式——抽象工厂模式源码,设计模式——抽象工厂模式源码
这个是http://blog.csdn.net/dawanganban/article/details/9875873博客中java设计模式的源代码。下载前请先看《设计模式——简单工厂》一文。
经典的设计模式————简单工厂模式,里面有实验文档和实验源代码还有课件助于你的学习
vs2010实现的软件设计模式——抽象工厂,是软件工程专业学生专业技能之一
Android之大话设计模式——:抽象工厂模式借鉴.pdf
Android之大话设计模式——:抽象工厂模式参考.pdf
主要介绍了Java设计模式——工厂设计模式详解,具有一定参考价值,需要的朋友可以了解下。
NULL 博文链接:https://maidoudao.iteye.com/blog/1328618
工厂模式: – 实现了创建者和调用者的分离。 – 详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 面向对象设计的基本原则: OCP(开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改...
设计模式C#描述之——简单工厂模式,让你学习C#的一种设计模式
java23种设计模式 工厂模式 ,抽象工厂,建造者模式,单态模式,原型模式
工厂方法模式之所以可以解决简单工厂的模式,是因为它的实现把具体产品的创建推迟到子类中,此 时工厂类不再负责所有产品的创建,而...下面看下工厂模式 的具体实现代码(这里还是以简单工厂模式中点菜的例子来实现):
简介 设计模式是为了解决一些出现的问题设计的解决方案。是长时间经验的总结,是根据...工厂模式 在类中实现一个接口创建指定对象,使一个类的实例化延迟到了子类。简单来说把类的创建都封装起来,只需要调用一个子类
JAVA设计模式总结之23种设计模式 一:设计模式之六大原则 总原则:开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭。...1.Abstract Factory(抽象工厂模式) 2.Adapter(适配器模式)......
利用JAVA设计模式——工厂模式实现对MYSQL数据库的增删改查
书名: 设计模式可复用面向对象软件的基础 英文原书名: Design Patterns:Elements of Reusable Object-Oriented software 作者: Erich Gamma 等 译者: 李英军 马晓星 蔡敏 刘建中 书号: 7-111-07575-7 页码: 254 定价...
写博客上传的代码:blog http://blog.csdn.net/t1234xy4/article/details/52424048
SETema5 软件设计模式——抽象工厂