在java的设计模式中,工厂模式被广泛使用,因此有必要了解一下什么是工厂模式,以及它所具有的的优点,应用场景等等......
一、定义:实例化对象,用工厂方法代替new操作。
二、如何实现
工厂模式主要是定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化,工厂方法把实例化的工作推迟到子类中去实现。
三、分类
- 工厂方法模式
- 抽象工厂模式
二者之间的对比:
- 工厂模式是一种极端情况下的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广。
- 工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构。
- 工厂模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。
四、例子(工厂方法模式)
首先,创建对应的接口
/** * 几何图形接口 * */ public interface Geometry { //创建几何图形 public void creat(); }
然后创建一系列接口的实现类
//实现类1:正方形 public class Square implements Geometry { @Override public void creat() { System.out.println("-------------正方形--------------"); } } //实现类2:长方形 public class Oblong implements Geometry { @Override public void creat() { System.out.println("-------------长方形--------------"); } } //实现类3:圆形 public class Rotundity implements Geometry { @Override public void creat() { System.out.println("-------------圆形--------------"); } }
接着需要编写工厂,不过我们先写测试方法
public class Test { public static void main(String[] args) { GeometryFactory factory = new GeometryFactory(); Geometry geometry = factory.getByClassKey("Rotundity"); geometry.creat(); } }
在测试方法中,我们调用工厂中的getByClassKey方法,我们希望传过去一个值,工厂中的方法能够根据传的值直接定义到我们需要实例的对象,因此我们需要进行一个封装,将传的值和对应的类名一一对应封装,类似于map中的键值对形式,在java中封装值可以写在properties文件中,二者之间用等号连接。
Square=com.xm.entity.Square Oblong=com.xm.entity.Oblong Rotundity=com.xm.entity.Rotundity
封装完对应关系后,我们需要写一个创建一个类来专门解读properties文件中的对应关系,其原理是将其对应的关系存放进一个map中,等号左边作为map的key值,右边作为map的value值。
/** * properties文件读取工具 * */ public class ReaderProperties { public Map<String,String> getProperties(){ Properties props = new Properties(); Map<String,String> map = new HashMap<String,String>(); try { InputStream in = getClass().getResourceAsStream("app.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); } } catch (IOException e) { e.printStackTrace(); } return map; } }
接下来就要编写工厂方法了,在工厂类中,我们使用反射来通过类名直接找到我们需要的类,这样代码更具有通用性和扩展性。
public class GeometryFactory { //根据类名来生产对象 public Geometry getByClassKey(String key){ Map<String,String> map = new ReaderProperties().getProperties(); try { Geometry geometry = (Geometry)Class.forName(map.get(key)).newInstance(); return geometry; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } }
五、工厂模式的常见应用
1、JDBC
JDBC是一种用于执行SQL语句的java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成。
2、spring beanfactory
BeanFactory,作为Spring基础的IOC容器,是Spring的一个Bean工厂,如果单从工厂模式的角度思考,它就是用来“生产Bean”,然后提供给客户端。
六、工厂模式的作用
- 系统可以在不修改具体工厂角色的情况下引入新的产品。
- 客户端不必关心对象如果创建,明确了职责。
- 更好的理解面向对象的原则,面向接口编程,而不是面向实现编程。
七、工厂模式的适用场景
- 一个系统应当不依赖于产品类实例被创立,组成,和表示的细节。这对于所有形态的工厂模式都是重要的。
- 这个系统的产品有至少一个的产品族。
- 同属于同一产品族的产品是设计成在一起使用的,这一约束必须得在系统的设计中体现出来。
- 不同的产品以一系列的接口的面貌出现,从而使系统不依赖与接口实现的细节。