本文共 6429 字,大约阅读时间需要 21 分钟。
一、分析程序的耦合
1、一个强耦合性的代码:
可见下面的代码有许多new,代码之间有很强的耦合性。
package com.lyc.dao.impl;import com.lyc.dao.IAccountDao;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:31 2020/6/7 * @Modified by: * 账户的持久层实现类 */public class AccountDaoImpl implements IAccountDao { public void saveAccount() { System.out.println("保存了账户"); }}
package com.lyc.dao;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:29 2020/6/7 * @Modified by: * 账户的持久层接口 */public interface IAccountDao { void saveAccount();}
package com.lyc.service.impl;import com.lyc.dao.IAccountDao;import com.lyc.dao.impl.AccountDaoImpl;import com.lyc.service.IAccountService;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:26 2020/6/7 * @Modified by: * 账户的业务层实现类 */public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao = new AccountDaoImpl();//业务层调用持久层 public void saveAccount() { accountDao.saveAccount(); }}
package com.lyc.service;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:24 2020/6/7 * @Modified by: * 账户业务层的接口 */public interface IAccountService { void saveAccount();}
package com.lyc.ui;import com.lyc.service.IAccountService;import com.lyc.service.impl.AccountServiceImpl;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:36 2020/6/7 * @Modified by: * 模拟一个表现层,用来调用业务层 */public class Client { public static void main(String[] args) { IAccountService as=new AccountServiceImpl(); as.saveAccount(); }}
2、用BeanFactory
工厂解耦
##这里存放的都是些 可重复使用的组件 BeanaccountService=com.lyc.service.impl.AccountServiceImplaccountDao=com.lyc.dao.impl.AccountDaoImpl
package com.lyc.factory;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.Properties;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:43 2020/6/7 * @Modified by: * 一个创建Bean对象的工厂 * Bean 在计算机英语中,有可重用组件,反复使用 * JavaBean:用java语言编写的可重用组件。 * javabaen >> 实体类 * 它就是创建我们的service和dao对象的 * * 第一个:需要一个配置文件来配置我们的service和dao * 配置文件内容要包含:唯一标识=全限定类名(key value) * 第二个:通过读取配置文件中配置的内容,反射创建对象 * 配置文件可以选用xml或properties */public class BeanFactory { //定义一个Properties对象 private static Properties properties; //一、使用静态代码块为Properties对象赋值 static { try { //程序的耦合不能消除,尽量降低 //第一步,获取实例化对象 properties= new Properties(); //第二步获取properties文件的流对象// InputStream in = new FileInputStream("");//这里用new,添加路径,未必能保证以后的路径也一致 InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"); properties.load(in); } catch (IOException e) { //如果properties文件没有获取成功的话,后面的事都干不了 throw new ExceptionInInitializerError("初始化properties失败"); } } //Object用一个泛型类 //二、 public static Object getBean(String beanName){ //根据Bean的名称获取Bean对象 Object bean = null; try { String beanPath = properties.getProperty(beanName); //1、用反射的方式来创建对象 bean //2、有能反射的全限定类名 bean.properties //通过读取配置文件的方式来去反射得到对象 bean = Class.forName(beanPath).newInstance(); //因为newInstance是每次都初始化,所以写出来的是多例的,每条线来访问的时候,都创建一个新的对象 } catch (Exception e) { e.printStackTrace(); } return bean; }}
写到这里,控制层用来解耦的工厂方式的就写好了,接下来要修改service层
里面依赖的dao
和ui层
里面依赖的service
的。
//创建对象 做了修改 用上了Bean工厂解耦 IAccountService as = (IAccountService) BeanFactory.getBean("accountService"); private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");
3、分析BeanFactory
工厂解耦的问题并改造
上述第2点用到的是多例,现在修改为单例的:
package com.lyc.factory;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import java.util.Properties;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:43 2020/6/7 * @Modified by: * 一个创建Bean对象的工厂 * Bean 在计算机英语中,有可重用组件,反复使用 * JavaBean:用java语言编写的可重用组件。 * javabaen >> 实体类 * 它就是创建我们的service和dao对象的 * * 第一个:需要一个配置文件来配置我们的service和dao * 配置文件内容要包含:唯一标识=全限定类名(key value) * 第二个:通过读取配置文件中配置的内容,反射创建对象 * 配置文件可以选用xml或properties */public class BeanFactory { //定义一个Properties对象 private static Properties properties; //定义一个Map,用于存放我们创建的对象,我们称之为容器 private static Mapbeans; //一、使用静态代码块为Properties对象赋值 static { //静态类在加载的时候执行一次 try { //程序的耦合不能消除,尽量降低 //第一步,获取实例化对象 properties= new Properties(); //第二步获取properties文件的流对象// InputStream in = new FileInputStream("");//这里用new,添加路径,未必能保证以后的路径也一致 InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"); properties.load(in); //第三步实例化容器 beans = new HashMap (); //取出配置文件中所有的key,返回的枚举类型 Enumeration keys=properties.keys(); while(keys.hasMoreElements()){ //取出每个key String key=keys.nextElement().toString(); //根据key获取value值 String beanPath = properties.getProperty(key); //反射创建对象 Object value = Class.forName(beanPath).newInstance(); //把key和value存入容器中 beans.put(key,value); } } catch (Exception e) { //如果properties文件没有获取成功的话,后面的事都干不了 throw new ExceptionInInitializerError("初始化properties失败"); } } //Object用一个泛型类 //二、 public static Object getBean(String beanName){ //根据beanName获取对象 //单例的 return beans.get(beanName); }}
package com.lyc.service.impl;import com.lyc.dao.IAccountDao;import com.lyc.factory.BeanFactory;import com.lyc.service.IAccountService;/** * @Author:钰兔大王 * @Description: * @Date: Create in 20:26 2020/6/7 * @Modified by: * 账户的业务层实现类 */public class AccountServiceImpl implements IAccountService { // private IAccountDao accountDao = new AccountDaoImpl();//业务层调用持久层 private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao"); private int i=1; //调用方法的时候会创建一个i,在static里面用Map存放了所有beanPath后,就变成了单例,在Client创建多少个对象,i就变化几次 public void saveAccount() { // int i=1;//如果写到这里,每次都会创建一个新的i,都会等于1 accountDao.saveAccount(); System.out.println(i); //类里的方法来操作类的成员 i++; }}
qq_2405310636的博客:qq此号,有疑问可联系我。创作不易,引用请注明出处。
转载地址:http://xttzi.baihongyu.com/