框架漫谈之spring(一)工厂模式实现程序解耦,spring框架的引出
2017-09-24 22:29
585 查看
1.程序的耦合度
我们来看如下的代码// 表现层 public class UserController { public static void main(String[] args) { IUserService userService = new UserServiceImpl(); userService.saveUser(); } }
// 业务实现类接口 public interface IUserService { void saveUser(); } // 业务实现类 public class UserServiceImpl implements IUserService { private UserDao userDao = new UserDao(); public void saveUser() { userDao.saveUser(); }
// 持久层接口 public interface IUserDao{ void saveUser(); } // 持久层实现类 public class UserDaoImpl implements IUserDao { System.out.println("保存一个用户"); }
该程序模拟了某网站注册用户的流程,我们来看上述的程序,表面上来看是没有一点问题的,但仔细的看。表现层与业务层、业务层与持久层紧紧的互相依赖关联,这与我们开发程序的高内聚低耦合原则相违背。我们也来看一看原始的JDBC程序
//注册mysql驱动 DriverManager.deregisterDriver(new com.mysql.jdbc.Driver());
点进jdbc注册驱动的源码可以知道,当加载这个类时候 已经注册,这样相当于注册了两次。从程序的角度的来看即使注册了2次所浪费的效率基本上可以忽略不计。原始的JDBC注册驱动 紧紧的依赖着mysql的jar包,一旦没有mysql的jar包编译时就会报错,所以我们真正写JDBC注册驱动的是用这行代码
//注册mysql驱动 改进了注册2次的问题 并且做到了编译时候不依赖 Class.forName("com.mysql.jdbc.Driver");
从JDBC和上述模拟用户注册的案例来看,当有一个类在编译时候,紧紧依赖于另外一个类的存在.
当没有依赖类存在时,程序不能编译.此时我们就称这两个类有很想的依赖关系,高耦合度
开发中应该遵循的依赖原则:编译时不依赖,运行时在依赖。
2.工厂模式实现程序解耦
使用工厂模式:工厂为我们创建类的对象,从而解决层和层之间的依赖关系。
这种依赖关系我们也叫,程序的耦合。
package test.factory; import test.dao.IUserDao; /** * 工厂模式: 用于削减计算机程序耦合 * * @author ZhuPengWei * @Date 2017年9月24日 */ public class BeanFactory { private static BeanFactory factory; static { factory = new BeanFactory(); } // 单例模式:私有化构造函数 private BeanFactory() { } // 提供一个公共方法,获取该类的实例 public static BeanFactory newInstance() { return factory; } /** * 用于生成一个的持久层实现类对象 * * @return */ public IUserDao getUserDao() { try { return (IUserDao) Class.forName("test.dao.impl.UserDao").newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } }
用户业务层实现类也作出如下的改进
public class UserServiceImpl implements IUserService { // private IUserDao userDao = new UserDao(); IUserDao userDao = BeanFactory.newInstance().getUserDao(); public void saveUser() { userDao.saveUser(); } }
3.工厂模式改进
仔细的来看,上面的工厂模式存在了大量的问题,首先它在反射创建对象时候使用了硬编码,存在硬编码的问题。其次此工厂模式不利于程序的扩充,首先开发需要写获取持久层的方法以及业务层的方法,一旦有新的解耦需求工厂类就得添加新的方法,这样是十分不利于维护的。下面,将对于这两点进行改进在类路径下创建bean.properties
USERDAO = test.dao.impl.UserDaoImpl USERSERVICE =test.service.impl.UserServiceImpl
package test.factory; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.ResourceBundle; /** * 工厂模式: 用于削减计算机程序耦合 * * @author ZhuPengWei * @Date 2017年9月24日 */ public class BeanFactory { // 此类可以通过静态方法获取对象,参数是资源文件的名称(不写程序的扩展名)。 // 底层是类加载器,因此只能读取类路径下的资源文件(src目录下)。 private static ResourceBundle bundle = ResourceBundle.getBundle("bean"); // 定义一个容器,用于存储配置文件中配置的对象 private static Map<String, Object> beans = new HashMap<String, Object>(); private static BeanFactory factory; static { factory = new BeanFactory(); // 初始化容器 Enumeration<String> keys = bundle.getKeys(); while (keys.hasMoreElements()) { // 取出每一个key String key = keys.nextElement(); // 根据key,获取全限定类名 String classPath = bundle.getString(key); try { // 根据classPath反射创建类对象 Object object = Class.forName( classPath).newInstance(); // 存入map中 beans.put(key, object); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { throw new ExceptionInInitializerError("初始化容器失败!"); } } } // 单例模式:私有化构造函数 private BeanFactory() { } // 提供一个公共方法,获取该类的实例 public static BeanFactory newInstance() { return factory; } /** * 根据参数获取Bean对象 * @param beanName 参数 * @return Bean对象 */ public Object getBean(String beanName){ return beans.get(beanName); } /** * 用于生成一个的持久层实现类对象 * 由于返回值是一个固定的接口,所以导致了创建其他类对象时,必须写新的方法 * @return */ // public IUserDao getUserDao() { // try { // return (IUserDao) Class.forName("test.dao.impl.UserDao").newInstance(); // } catch (Exception e) { // throw new RuntimeException(e); // } // } }
package test.service.impl; import test.dao.IUserDao; import test.factory.BeanFactory; import test.service.IUserService; /** * 用户业务层实现类 * * @author ZhuPengWei * @Date 2017年9月24日 */ public class UserServiceImpl implements IUserService { // private IUserDao userDao = new UserDao(); //IUserDao userDao = BeanFactory.newInstance().getUserDao(); //改造后的方法:获取bean对象,根据bean名称。得到的对象是Object,需要强转 private IUserDao userDao = (IUserDao) BeanFactory.newInstance().getBean("USERDAO"); public void saveUser() { userDao.saveUser(); } }
4.spring框架引出
那我们为什么要用spring呢?首先它的好处之一就是方便解耦简化开发。spring是一个大工厂,可以将所有对象创建和依赖维护交给spring去管理
暂时本文也只是说明了这一个好处。
什么是spring框架?
spring是一个开源框架。它是为了解决企业应用开发的复杂性而创建的,框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供继承的框架。spring使用基本的JAVABean来完成以前只可能由EJB完成的事情。spring的用途也不仅仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从spring中收益。spring的核心就是控制反转(ioc)和面向切面(aop)。简单的来说,spring是一个分层的一站式轻量级开源框架
spring是用来干什么的?
这个介绍的不错
相关文章推荐
- DAO层与Service业务逻辑层的解耦实现之Factory工厂模式
- Spring实现两种设计模式:工厂模式和单态模式
- [Spring] IOC的实现原理—反射与工厂模式
- 基于Spring注解实现的工厂模式
- Spring 实现两种设计模式:工厂模式和单态模式
- 【JavaEE学习笔记】Spring_01_工厂模式,Spring小程序,IoC控制反转
- java web 项目实现 耦合-解耦 解决方案----工厂模式入门级别
- 工厂模式 - 程序实现(java)
- 基于配置文件的工厂设计模式实现,并且做到对象的单例,类似于spring的ioc
- 基于Spring注解实现工厂模式
- asp.net mvc中自行搭建实现工厂模式的spring.net+三层架构 (15-4-20)
- 利用工厂设计模式实现业务层和dao层的解耦
- 使用单例和工厂设计模式实现dao实现层的解耦
- java:运用工厂模式+反射实现可插拔的程序
- 设计模式的应用-工厂方法实现3层模型解耦
- SpringIoc 和 工厂模式(反射实现)
- 反射 实现工厂模式 和 spring IOC 实现原理
- asp.net mvc中自行搭建实现工厂模式的spring.net+三层架构 (15-4-20)
- 设计模式C++实现(1)——工厂模式
- PetShop4.0 工厂模式及Profile Provider实现