java设计模式之工厂模式

在java的设计模式中,工厂模式被广泛使用,因此有必要了解一下什么是工厂模式,以及它所具有的的优点,应用场景等等......

一、定义:实例化对象,用工厂方法代替new操作。

二、如何实现

工厂模式主要是定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化,工厂方法把实例化的工作推迟到子类中去实现。

三、分类

  1. 工厂方法模式
  2. 抽象工厂模式

二者之间的对比:

  1. 工厂模式是一种极端情况下的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广。
  2. 工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构。
  3. 工厂模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。

四、例子(工厂方法模式)

首先,创建对应的接口

/**
 * 几何图形接口
 * */
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”,然后提供给客户端。

六、工厂模式的作用

  1. 系统可以在不修改具体工厂角色的情况下引入新的产品。
  2. 客户端不必关心对象如果创建,明确了职责。
  3. 更好的理解面向对象的原则,面向接口编程,而不是面向实现编程。

七、工厂模式的适用场景

  1. 一个系统应当不依赖于产品类实例被创立,组成,和表示的细节。这对于所有形态的工厂模式都是重要的。
  2. 这个系统的产品有至少一个的产品族。
  3. 同属于同一产品族的产品是设计成在一起使用的,这一约束必须得在系统的设计中体现出来。
  4. 不同的产品以一系列的接口的面貌出现,从而使系统不依赖与接口实现的细节。
原文地址:https://www.cnblogs.com/libinhyq/p/9566683.html