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

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

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与Kotlin版)

    Kotlin基础知识的学习,请参考之前的文章: Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次尝试用Kotlin实现Android ...

  3. [Java反射机制]用反射改进简单工厂模式设计

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

  4. java反射机制(工厂模式)

    http://www.phpddt.com/dhtml/338.html java里面没有typeof,js有. 我终于实现了用反射机制编写的工厂模式.java反射在工厂模式可以体现. 包含产品接口类 ...

  5. Java实验项目三——简单工厂模式

    Program: 请采用采用简单工厂设计模式,为某个汽车销售店设计汽车销售系统,接口car至少有方法print(), 三个汽车类:宝马.奥迪.大众 (属性:品牌,价格),在测试类中根据客户要求购买的汽 ...

  6. Java设计模式2:简单工厂模式

    简单工厂模式 简单工厂模式是类的创建模式,又叫做静态工厂方法模式.简单工厂模式由一个工厂对象决定生产出哪一种产品类的实例. 为什么要使用简单工厂模式 原因很简单:解耦. A对象如果要调用B对象,最简单 ...

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

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

  8. Java设计模式(一) 简单工厂模式不简单

    摘要:本文介绍了简单工厂模式的概念,优缺点,实现方式,以及结合Annotation和反射的改良方案(让简单工厂模式不简单).同时介绍了简单工厂模式(未)遵循的OOP原则.最后给出了简单工厂模式在JDB ...

  9. java反射机制的简单介绍

    参考博客: https://blog.csdn.net/mlc1218559742/article/details/52754310 先给出反射机制中常用的几个方法: Class.forName (& ...

随机推荐

  1. python selenium --调用js

    转自:http://www.cnblogs.com/fnng/p/3230768.html 本节重点: 调用js方法 execute_script(script, *args) 在当前窗口/框架 同步 ...

  2. Cocos2d-X中的ZORDER和Tag

    ZORDER:是描写叙述渲染顺序的值,每一个CCNode都有ZORDER,默认是0 ZORDER越大,越后面绘制 假设ZORDER同样.那么看arrival顺序.先增加的节点先绘制 ZORDER仅仅在 ...

  3. python操作sqlserver

    # coding=gbk import sys   import pymssql #尝试数据库连接 try:     conn = pymssql.connect(host="192.168 ...

  4. iOS9新特性

    本文主要是说一些iOS9适配中出现的坑,如果只是要单纯的了解iOS9新特性可以看瞄神的开发者所需要知道的 iOS 9 SDK 新特性.9月17日凌晨,苹果给用户推送了iOS9正式版,随着有用户陆续升级 ...

  5. Compiler Error C2872: ambiguous symbol

    参考资料:http://blog.csdn.net/greytree/article/details/354530 刚才写的程序报错ERROR C2872(CL.exe)原因很简单 ZThread有定 ...

  6. [转]c++ 为什么要将基类的析构函数声明为Virtual?

    http://www.cnblogs.com/alephsoul-alephsoul/archive/2012/10/12/2721410.html

  7. [转]解决Access restriction: The type * is not accessible due to restrict

    我在eclipse使用org.omg下的东西的时候报此错误 我用的第一种方法解决了问题 转自:http://blog.sina.com.cn/s/blog_6714fba70100x6mz.html ...

  8. 【网络爬虫】Httpclient4.X中使用HTTPS的方法采集12306网站

    HttpClient请求https的实例: package train; import java.io.IOException; import java.security.NoSuchAlgorith ...

  9. linux学习笔记23--时间命令date和cal

    在linux环境中,不管是编程还是其他维护,时间是必不可少的,也经常会用到时间的运算,熟练运用date命令来表示自己想要表示的时间,肯定可以给自己的工作带来诸多方便. 1.命令格式: date [参数 ...

  10. 猫猫学iOS 之微博项目实战(5)微博自己定义搜索框searchBar

    猫猫分享.必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用 ...