如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取实际数据库操作类实例。

  下面举一个最简单的工厂模式例子:

interface IAnimal {
void talk();
}
class Cat implements IAnimal {
@Override
public void talk() {
System.out.println("I'm cat");
}
}
class Dog implements IAnimal {
@Override
public void talk() {
System.out.println("I'm dog");
}
}
class AnimalFactory {
private AnimalFactory() {}
public static IAnimal getInstance(String animal) {
if ("Cat".equals(animal)) {
return new Cat();
} else if ("Dog".equals(animal)) {
return new Dog();
} else {
return null;
}
}
}
public class Main {
public static void main(String[] args) throws ParseException{
IAnimal animal = AnimalFactory.getInstance("Cat");
animal.talk();
animal = AnimalFactory.getInstance("Dog");
animal.talk();
}
}

  最简洁的例子了, 客户端首先想要生成一个Cat的实例,传入“Cat”,一阵操作之后,又想生成Dog实例,直接传入“Dog”到工厂里面拿,接着继续使用。

  观察工厂类,里面是根据客户端传过来的字符串手动new一个实例并返回,那如果这个工厂刚好要容纳好几百种实例的返回,并可能会不定时添加新的实例类型,那岂不是每次都要去修改工厂类,有没有一个办法我写一次工厂类,然后工厂类能自动产生并返回客户端需要的实例? 这个时候我们可以利用反射的机制,根据客户端传进来的字符串,运用反射原理去寻找我们所要的实体类。首先呢,接口和实体类都要写还给他的,接着呢修改工厂类如下:

class AnimalFactory {
private AnimalFactory() {}
public static IAnimal getInstance(String animal) {
try {
Class cls = Class.forName(animal);
return (IAnimal) cls.newInstance();
} catch (Exception e) {
return null;
}
}
}

首先由Class类型的静态方法forName(String className)找到这个类并返回这个类的Class类型对象, 此时找不到的话会抛出ClassNotFoundException,抛出异常了就返回null咯。

然后用Class对象的newInstance()方法产生一个实例,这个实例就是forName函数找到的实体类实例。相当于用默认构造函数产生一个实例,所以此处也会抛出异常,比如默认构造函数是私有类型的情况下。

接着,如果我产生的实例都需要根据传入的参数对应去实例化呢,这个时候,我们可以利用反射去找有相应参数的构造函数,再生成一个实例就好啦。

interface IAnimal {
void talk();
}
class Cat implements IAnimal {
private String name;
public Cat(String name) {
this.name = name;
}
@Override
public void talk() {
System.out.println("I'm cat:" + this.name);
}
}
class Dog implements IAnimal {
private String name;
public Dog(String name) {
this.name = name;
}
@Override
public void talk() {
System.out.println("I'm dog:" + this.name);
}
}
class AnimalFactory {
private AnimalFactory() {}
public static IAnimal getInstance(String animal, String name) {
try {
Class cls = Class.forName(animal);
Constructor<?> con = cls.getConstructor(String.class);
return (IAnimal)con.newInstance(name);
} catch (Exception e) {
return null;
}
}
}
public class Main {
public static void main(String[] args) throws ParseException{
IAnimal animal = AnimalFactory.getInstance("Cat", "Miao");
animal.talk();
animal = AnimalFactory.getInstance("Dog", "Wang");
animal.talk();
}
}

在工厂类中,我们如果找到这个类的Class类型对象时,就用这个Class对象去找对应的Constructor对象,getConstructor方法接受无数个参数,根据需要指定我们要找的这个构造函数参数类型是什么,例子中这个类型是String,所以我们用String.class去指定这个类型便是String类型,接着用这个Constructor对象,newInstance(String para)实例化并返回。

至此,用反射改进传统工厂模式步骤完成。 如有写的不妥之处,欢迎之处斧正。

尊重知识产权,转载引用请通知作者并注明出处!

[Java反射机制]用反射改进简单工厂模式设计的更多相关文章

  1. 1、使用简单工厂模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程

    1.使用简单工厂模式设计能够实现包含加法(+).减法(-).乘法(*).除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果.要求使用相关的工具绘制UML类图并严格按照类图的设计编写程 ...

  2. 简单工厂模式设计(java反射机制改进)

    如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...

  3. Java 设计模式系列(二)简单工厂模式和工厂方法模式

    Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...

  4. java面向接口编程之制定标准和简单工厂模式

    制定一个标准,让别人去实现或者说满足它! Eg: interface USB{//定义USB标准 void useUSB();//USB有使用USB的行为 } 简单工厂模式 构建一个工厂出来,在里面进 ...

  5. java之设计模式工厂三兄弟之简单工厂模式

    [学习难度:★★☆☆☆,使用频率:★★★☆☆] 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式.本章将要学习的简单工厂模式是工厂方法模式的& ...

  6. iOS 简单工厂模式

    iOS 简单工厂模式 什么是简单工厂模式? 简单工厂模式中定义一个抽象类,抽象类中声明公共的特征及属性,抽象子类继承自抽象类,去实现具体的操作.工厂类根据外界需求,在工厂类中创建对应的抽象子类实例并传 ...

  7. 简单工厂模式(Simple Factory Pattern)

    简单工厂模式概述 定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被 ...

  8. (转)java反射机制及简单工厂模式

    第一步,定义一个接口类 package factory.face; /** * 接口,为了保证返回的对象可以统一用 Product接受 * @author Administrator */ publi ...

  9. Java反射+简单工厂模式总结

    除了 new 之外的创建对象的方法 通过 new 创建对象,会使得程序面向实现编程,先举个例子,某个果园里现在有两种水果,一种是苹果,一种是香蕉,有客户想采摘园子里的水果,要求用get()方法表示即可 ...

随机推荐

  1. TreeNode.trage的使用

    对于trage的使用 msdn是这样解释的 TreeNode.Target 属性 .NET Framework 2.0 其他版本 注意:此属性在 .NET Framework 2.0 版中是新增的. ...

  2. EntityFramework Core 2.0 Explicitly Compiled Query(显式编译查询)

    前言 EntityFramework Core 2.0引入了显式编译查询,在查询数据时预先编译好LINQ查询便于在请求数据时能够立即响应.显式编译查询提供了高可用场景,通过使用显式编译的查询可以提高查 ...

  3. poi 导入导出的api说明(大全)

    原文链接:http://www.cnblogs.com/qingruihappy/p/8443101.html poi 导入导出的api说明(大全) 一. POI简介 ApachePOI是Apache ...

  4. Redis入门必读,The Little Redis Book中文版

    csdn的博客都要搬到这里了 The Little Redis Book中文版 入门 The Little Redis Book中文版 第一章 - 基础知识 The Little Redis Book ...

  5. Spring 之BeanFactory(转)

    BeanFactory是Spring的“心脏”.它就是Spring IoC容器的真面目. Spring使用BeanFactory来实例化.配置和管理Bean.但是,在大多数情况我们并不直接使用Bean ...

  6. 过滤器(Filter)和拦截器(Interceptor)

    之前总是弄混这两者,今天看了几篇文章,小结一下在这里. Filter介绍 Filter可以认为是Servlet的一种"加强版",它主要用于对用户请求进行预处理,也可以对HttpSe ...

  7. Apace Ignite剖析

    1.概述 Apache Ignite和Apache Arrow很类似,属于大数据范畴中的内存分布式管理系统.在<Apache Arrow 内存数据>中介绍了Arrow的相关内容,它统一了大 ...

  8. [JSOI2004]平衡点

    题面在这里 题意 ...见链接吧 sol 在此发一篇模拟退火的题解 不得不说luogu的数据真是太良心啦 一句话解释模拟退火:在一个慢慢缩小的范围内随机状态寻找最优解,当转移状态更优时直接接受,当当前 ...

  9. canvas练手项目(二)——各种操作基础

    想想应该在canvas上面作画了,那么就不得不提到事件了. (打着canvas的旗号,写着mouse事件.挂羊头卖狗肉!哈哈哈哈哈~) 先来看一看HTML事件属性,我们要用的就是Mouse事件,就先研 ...

  10. 百度定位一直出现4.9E -324的问题解决方法

    问题:华为mate10一直在申请百度定位的时候出现此问题并且定位权限和定位服务都打开的情况也是返回这个参数 明显没有定位成功,其他手机暂时没有出现(只要打开定位权限就会立即定位成功) 解决:在定位之前 ...