您的位置:首页 > 编程语言 > Java开发

框架漫谈之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是用来干什么的?

这个介绍的不错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: