[Java反射机制]用反射改进简单工厂模式设计
如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取实际数据库操作类实例。
下面举一个最简单的工厂模式例子:
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、使用简单工厂模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程
1.使用简单工厂模式设计能够实现包含加法(+).减法(-).乘法(*).除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果.要求使用相关的工具绘制UML类图并严格按照类图的设计编写程 ...
- 简单工厂模式设计(java反射机制改进)
如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...
- Java 设计模式系列(二)简单工厂模式和工厂方法模式
Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...
- java面向接口编程之制定标准和简单工厂模式
制定一个标准,让别人去实现或者说满足它! Eg: interface USB{//定义USB标准 void useUSB();//USB有使用USB的行为 } 简单工厂模式 构建一个工厂出来,在里面进 ...
- java之设计模式工厂三兄弟之简单工厂模式
[学习难度:★★☆☆☆,使用频率:★★★☆☆] 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式.本章将要学习的简单工厂模式是工厂方法模式的& ...
- iOS 简单工厂模式
iOS 简单工厂模式 什么是简单工厂模式? 简单工厂模式中定义一个抽象类,抽象类中声明公共的特征及属性,抽象子类继承自抽象类,去实现具体的操作.工厂类根据外界需求,在工厂类中创建对应的抽象子类实例并传 ...
- 简单工厂模式(Simple Factory Pattern)
简单工厂模式概述 定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被 ...
- (转)java反射机制及简单工厂模式
第一步,定义一个接口类 package factory.face; /** * 接口,为了保证返回的对象可以统一用 Product接受 * @author Administrator */ publi ...
- Java反射+简单工厂模式总结
除了 new 之外的创建对象的方法 通过 new 创建对象,会使得程序面向实现编程,先举个例子,某个果园里现在有两种水果,一种是苹果,一种是香蕉,有客户想采摘园子里的水果,要求用get()方法表示即可 ...
随机推荐
- Caused by: java.lang.ClassNotFoundException: com.mchange.v2.ser.Indirector
1.错误描述 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -help ...
- Flex动态获取方法报错
1.错误描述 2.错误原因 由于Flex文件修改后,需要将其编译成swf文件,刚修改的方法没有编译,再加上历史缓存的原因,导致报错 3.解决办法 将Flex项目重新clean一下,并将MyEclips ...
- cfDNA基本知识
定义 Circulating free DNA or Cell free DNA (cfDNA):循环游离DNA或者细胞游离DNA,释放到血浆中的降解的DNA片段. https://en.wikipe ...
- xml的SAX解析和dom解析的区别
一,区别 DOM解析 SAX解析 原理: 一次性加载xml文档,不适合大容量的文件读取 原理: 加载一点,读取一点,处理一点.适合大容量文件的读取 DOM解析可以任意进行增删改成 SAX解析只能读取 ...
- Android App性能评测分析-流畅度篇
1.前言 在手机App竞争越来越激烈的今天,Android App的各项性能特别是流畅度不如IOS,安卓基于java虚拟机运行,触控响应的延迟和卡顿比IOS系统严重得多.一些下拉上滑.双指缩放快速打字 ...
- 在VCS仿真器中使用FSDB
FSDB(Fast Signal Database)是Verdi支持的文件格式,用于保存仿真产生的信号波形.据Verdi文档说明,FSDB比标准的VCD格式节省磁盘空间,处理速度更快.要用VCS仿真器 ...
- 【BZOJ1899】午餐(动态规划)
[BZOJ1899]午餐(动态规划) 题面 BZOJ 题解 我太弱了 这种\(dp\)完全做不动.. 首先,感性理解一些 如果所有人都要早点走, 那么,吃饭时间长的就先吃 吃饭时间短的就晚点吃 所以, ...
- [Luogu3377]【模板】左偏树(可并堆)
题面戳我 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删除或第x和第y个数 ...
- [SPOJ]DISUBSTR:Distinct Substrings&[SPOJ]SUBST1:New Distinct Substrings
题面 Vjudge Vjudge Sol 求一个串不同子串的个数 每个子串一定是某个后缀的前缀,也就是求所有后缀不同前缀的个数 每来一个后缀\(suf(i)\)就会有,\(len-sa[i]+1\)的 ...
- 谷歌chrome 插件(扩展)开发——谈谈安装
chrome extension 安装的方式简单,打包方式也是非常简单的. 官方给出了三种安装方式: Chrome Web Store:把你的扩展程序上传到Chrome Web Store, &q ...