设计模式快速学习(一)工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。我们熟悉的Spring 的 bean 工厂等。
直接上demo.先代码,后介绍。
1. 编写接口Shape
Shape .java
/** * 一个接口:关于形状 * Created by Fant.J. */ public interface Shape { /** * 描述方法 */ void describe(); }
2. 编写实现类
Circle .java
/** * Created by Fant.J. */ public class Circle implements Shape { /** * 描述方法 */ @Override public void describe() { System.out.println("我是个圆形"); } }
Rectangle .java
/** * Created by Fant.J. */ public class Rectangle implements Shape { /** * 描述方法 */ @Override public void describe() { System.out.println("我是一个长方形"); } }
3. 编写工厂类ShapeFactory
ShapeFactory .java
/** * 形状工厂(你可以通过我获取 相应的实例化对象) * Created by Fant.J. */ public class ShapeFactory { public Shape getShape(String type){ if (type == null){ return null; } if ("CIRCLE".equals(type)){ return new Circle(); }else if ("RECTANGLE".equals(type)){ return new Rectangle(); } return null; } }
4. 测试
/** * Created by Fant.J. */ public class Test { public static void main(String[] args) { ShapeFactory shapeFactory = new ShapeFactory(); //获取 圆形 实例化对象 Shape circle = shapeFactory.getShape("CIRCLE"); //调用对象方法 circle.describe(); //获取 长方形 实例化对象 Shape rectangle = shapeFactory.getShape("RECTANGLE"); //调用方法 rectangle.describe(); } }
我是个圆形 我是一个长方形
5. 进阶
提问:如果你是一个爱动脑筋的人,你会发现,它和Bean工厂的作用是相似的,但是Bean工厂是这样实现的吗?它会自动去写if语句去创建实例对象吗?
答案肯定是不是的。
当然,我在这里不会像spring 的bean工厂一样,把它的逻辑写出来,因为人家已经是经过很多年的迭代的产品,封装的已经(目不忍视)太厚了,所以我把它的实现原理说明。
可能有些人都想到了,对,就是框架离不开的:反射机制(传送门),不怎么了解的可以很快的看一下我以前的一个文集。
5.1 优化工厂类代码
ShapeFactory.java
/** * 反射 */ public Object getShape(Class<? extends Shape> clazz){ Object object = null; try { object = Class.forName(clazz.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return object; }
5.2 测试
Object shape = (Rectangle)shapeFactory.getShape(Rectangle.class); ((Rectangle) shape).describe();
6 新的问题
如果我们忘记去对shapeFactory 做强制类型转换的话,那就是一个完全的object对象,使用不方便,那我们如何能够省略类型转换的这一步骤呢?
6.1 再优化工厂类
/** * 反射 + 泛型 */ public <T> T getShape(Class<? extends T> clazz){ T object = null; try { //实例化,并在这里做 类型转换 object = (T) Class.forName(clazz.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return object; }
6.2 测试类
Rectangle shape = shapeFactory.getShape(Rectangle.class); shape.describe();
我是一个长方形
我们可以看到,事实上也是做了强制类型转换的,只不过在ShapeFactory里做的,我们看不到而已,这种做法会大大方便我们使用。
7. 最后的甜点
经过第五点和第六点的学习,我们想想,spring 框架里 其实只有一个工厂,那就是BeanFactory,ApplicationContext 也需要用它来创建对象。那我们如何去写一个针对多个接口实现一个公共的工厂类呢?
/** * 针对多个接口实现一个公共的工厂类 */ public <T> Object getObject(Class<T> clazz) { if (clazz == null ) { return null; } Object obj = null; try { obj = Class.forName(clazz.getName()).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } return obj; }
8. 总结
留个思考题,我们在Spring 框架下,@Autowired 装配Bean 具体是完成什么样的操作呢,这可能也是工厂模式最好的总结说明。
希望能帮到大家,谢谢大家!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
为方便Java技术交流,特地开通免费qq群
点击链接加入群【Java技术交流】:https://jq.qq.com/?_wv=1027&k=53xQNnh 群号214821336
- 下一篇
第214天:Angular 基础概念
一、Angular 简介 1、什么是 AngularJS - 一款非常优秀的前端高级 JS 框架 - 最早由 Misko Hevery 等人创建 - 2009 年被 Google 公式收购,用于其多款产品 - 目前有一个全职的开发团队继续开发和维护这个库 - 有了这一类框架就可以轻松构建 SPA 应用程序 - 轻松构建 SPA(单一页面应用程序) - 单一页面应用程序: + 只有一个页面(整个应用的一个载体) + 内容全部是由AJAX方式呈现出啦的 - 其核心就是通过指令扩展了 HTML,通过表达式绑定数据到 HTML。 2、为什么使用 AngularJS - 更少的代码,实现更强劲的功能 - 将一些以前在后台开发中使用的思想带入前端开发 - 带领当前市面上的框架走向模式化或者架构化 3、AngularJS 的核心特性 - MVC - 模块化 - 自动化双向数据绑定 - 指令系统 4、相关链接 - http://www.apjs.net/ - http://www.angularjs.cn/ - http://docs.angularjs.cn/api - https://mater...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题