java学习笔记之反射—反射和工厂模式
简单工厂模式又称为静态工厂方法模式,它是由工厂对象来决定要创建哪一种类的实例化对象。
静态工厂代码:
class Factory{
private Factory() {}
public static IMessage getInstance(String className) {
if("NetMessage".equals(className)) {
return new NetMessage();return null;
}
}
子类和父接口的定义:
interface IMessage{
public void send();
}
class NetMessage implements IMessage{
@Override
public void send() {}
}
class CloudMessage implements IMessage{
@Override
public void send() {}
}
在这段代码之中,当传入的参数是“NetMessage”的时候,就返回一个NetMessage类的实例化对象,否则就返回null,代码很简单明了,但是该工厂只能创建NetMessage类的对象,当我有更多的类需要工厂去创建对象时,我就必须对工厂类进行修改,比如下面这段代码。
class Factory{
private Factory() {}
public static IMessage getInstance(String className) {
if("NetMessage".equals(className)) {
return new NetMessage();
}else if("CloudMessage".equals(className)) {
return new CloudMessage();
}
return null;
}
}
我希望工厂类可以创建CloudMessage类的对象,所以我对工厂类进行了以上的修改。但如果需要实例化的类的越来越多,难道我要不停的修改我的工厂类吗?这样未免太过麻烦。我每次增加一个类都要在工厂类里面多添加一个判断语句,但是如果我在工厂类里面通过反射进行对象实例化就可以解决这个问题。
反射与工厂模式相结合:
class Factory{
private Factory() {}
/**
* 获取接口实例化对象
* @param className 接口的子类
* @return 如果子类存在则返回指定接口实例化对象
*/
@SuppressWarnings("unchecked")
public static IMessage getInstance(String className) {
IMssage instance = null;
try {
instance = (IMssage) Class.forName(className).getDeclaredConstructor().newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return instance;
}
}
在工厂类中使用反射操作,这样一来,无论有多少种类,工厂类都不需要进行修改。但是这种工厂模式依然存在缺点,该工厂只能对IMesaage接口子类进行实例化,如果一个类没有实现该接口则无法通过工厂进行对象实例化。而代码之中可能存在不同的接口,为了解决这一问题,可以在工厂类之中使用泛型。
代码:
//利用反射机制实现的工厂设计模式最大的优势在于,对于接口子类的扩充不再影响工厂类的定义
class NewFactory{
private NewFactory() {}
/**
* 获取接口实例化对象
* @param className 接口的子类
* @param clazz 描述的是一个接口的类型
* @return 如果子类存在则返回指定接口实例化对象
*/
@SuppressWarnings("unchecked")
public static <T>T getInstance(String className,Class<T> clazz) {
T instance = null;
try {
instance = (T) Class.forName(className).getDeclaredConstructor().newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return instance;
}
}
这样一来,接口之类的扩充不再影响工厂类的定义,无论是哪一个接口的子类,都可以通过该工厂类进行对象的创建。
java学习笔记之反射—反射和工厂模式的更多相关文章
- 设计模式C++学习笔记之七(AbstractFactory抽象工厂模式)
抽象工厂,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类.对于工厂方法来说,抽象工厂可实现一系列产品的生产,抽象工厂更注重产品的组合. 看代码: 7.1.解释 main(),女 ...
- Java学习笔记之使用反射+泛型构建通用DAO
PS:最近简单的学了学后台Servlet+JSP.也就只能学到这里了.没那么多精力去学SSH了,毕竟Android还有很多东西都没学完.. 学习内容: 1.如何使用反射+泛型构建通用DAO. 1.使用 ...
- Java学习笔记54(反射详解)
反射概念: java反射机制是在运行状态中,对于任意一个类,都能知道所有属性和方法 对于任意一个对象都能调用它的任意一个方法和属性,这种动态获取和调用的功能称为java的反射机制 实际作用: 已经完成 ...
- Java学习笔记八(反射)
1.介绍 反射为Java程序在执行时提供了动态的能力.利用反射能够在执行时对程序进行动态的控制.本篇博客着重解说一下Java中的反射. 2.Class类的使用 在Java执行过程中,每一个类被载入后都 ...
- Java学习笔记--注解和反射
注解和反射 1. 注解 注解作用: 对程序做出解释 被其他程序读取 注解格式: @注释名,还可以添加一些参数值,例如@SuppressWarnings(value="unchecked&qu ...
- Java 学习笔记 使用synchronized实现生产者消费者模式
说明 Object.wait()使当前的线程进入到等待状态(进入到等待队列) Object.notifyAll() 唤醒等待中的全部线程 Object.notify() 随机唤醒一个线程 代码 con ...
- JAVA学习笔记—review基本知识[反射与异常]
JAVA学习笔记—review基本知识[反射与异常] 1.异常: 1.1异常的分类: Java会将所有的异常封装成对象,其根本父类为Throwable. Throwable有两个子类:Error 和E ...
- Java反射机制demo(七)—反射机制与工厂模式
Java反射机制demo(七)—反射机制与工厂模式 工厂模式 简介 工厂模式是最常用的实例化对象模式. 工厂模式的主要作用就是使用工厂方法代替new操作. 为什么要使用工厂模式?直接new不好吗? 直 ...
- Laravel学习笔记之PHP反射(Reflection) (上)
Laravel学习笔记之PHP反射(Reflection) (上) laravel php reflect 2.1k 次阅读 · 读完需要 80 分钟 3 说明:Laravel中经常使用PHP的反 ...
- [Java反射机制]用反射改进简单工厂模式设计
如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...
随机推荐
- implements Serializable有什么作用?
没有implements Serializable,你就不能通过rmi(包括ejb)提供远程调用.serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序 ...
- UML之二、建模元素(1)
本章介绍UML建模元素 1:Stereotype-也被称为类型.构造型 UML里的元素扩展,简单来说其功能就是在已有的类型上添加一些标记,类似于打个戳,从而生成新的东西. 简单的说加一句话来更加清楚准 ...
- Android中点击按钮获取星级评分条的评分
场景 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 将布局改为Lin ...
- ES相关知识
ElkStack介绍 对于日志来说,最常见的需求就是收集.存储.查询.展示,开源社区正好有相对应的开源项目:logstash(收集).elasticsearch(存储+搜索).kibana(展示),我 ...
- MySQL锁与事务隔离级别
一.概述 1.锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除了传统的计算资源(如CPU.RAM.IO等)的争用以外,数据也是一种供需要用户共享的资源.如何保证数据并发访 ...
- 使用 linux kernel +busybox 定制linux系统
目的: 了解linux的启动过程 主要内容: 1.grub 是启动程序的bootloader 2.linux-kernel 是linux的开源内核 3.busybox 是linux的工具集合 启动顺序 ...
- PHP0026:PHP 博客项目开发3
- Git操作 :从一个分支cherry-pick多个commit到其他分支
在branch1开发,进行多个提交,这时切换到branch2,想把之前branch1分支提交的commit都[复制]过来,怎么办? 首先切换到branch1分支,然后查看提交历史记录,也可以用sour ...
- mysql必知必会--数 据 过 滤
如何组合 WHERE 子句以建立功能更强的更高级的搜索条件?如何使用 NOT 和 IN 操作符? 组合 WHERE 子句 第6章中介绍的所有 WHERE 子句在过滤数据时使用的都是单一的条 件.为了进 ...
- SQL server 游标用法
declare @EmpCode varchar(50), @EmpName varchar(50), @EmpAddress varchar(200);declare curEmployee cur ...