zoukankan      html  css  js  c++  java
  • Spring带你飞(2)—— 当没用spring之前,我们如何解决程序的耦合问题

    首先我们先了解一下什么是程序的耦合,耦合指的是程序间的依赖关系。那么解耦的意思就是要降低程序间的依赖关系。在我们实际开发中:应该做到,编译期不依赖,运行时才依赖

    好了上面废话那么多,我们先来看一段程序。

    /**
     * @ClassName: AccountServiceImpl
     * @author: benjamin
     * @version: 1.0
     * @description: 账户业务层接口的实现类
     * @createTime: 2019/07/24/17:10
     */
    public class AccountServiceImpl implements IAccountService {
        private IAccountDao accountDao = new AccountDaoImpl();
        public void  saveAccount(){   
            System.out.println("业务层保存账户。。。");
        }
    }
    

    可以看到,此时业务层的代码调用了持久层的实体类,如果我们此时没有持久层实现类,那么编译不能通过。这种编译期间依赖关系,我们应该杜绝。

    工厂模式解耦

    ​ 在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。那么,这个读取配置文件, 创建和获取三层对象的类就是工厂。

    我们先来看一下项目的结构:

    1. 创建maven工程;

    2. 创建业务层接口和实现类

      /**
       * 账户的业务层接口
       * @ClassName: IAccountService
       * @author: benjamin
       * @createTime: 2019/07/24/17:08
       */
      public interface IAccountService {
          /**
           * 模拟保存账户
           */
          void saveAccount();
      }
      
      /**
       * @ClassName: AccountServiceImpl
       * @author: benjamin
       * @version: 1.0
       * @description: 账户业务层接口的实现类
       * @createTime: 2019/07/24/17:10
       */
      
      public class AccountServiceImpl implements IAccountService {
          private IAccountDao accountDao = new AccountDaoImpl();
      
          public void  saveAccount(){
              System.out.println("业务层保存账户。。。");
              accountDao.saveAccount();
          }
      }
      
    3. 创建持久层接口和实现类

      /**
       * 账户的持久层接口
       * @ClassName: IAccountDao
       * @author: benjamin
       * @createTime: 2019/07/24/17:07
       */
      public interface IAccountDao {
      
          /**
           * 模拟保存账户
           */
          void saveAccount();
      }
      
      /**
       * @ClassName: AccountDaoImpl
       * @author: benjamin
       * @version: 1.0
       * @description: 账户的持久层实现类
       * @createTime: 2019/07/24/17:10
       */
      
      public class AccountDaoImpl implements IAccountDao {
          public  void saveAccount(){
              System.out.println("保存了账户");
          }
      }
      
    4. 创建表现层

      /**
       * @ClassName: Client
       * @author: benjamin
       * @version: 1.0
       * @description: 模拟一个表现层,用于调用业务层
       * @createTime: 2019/07/24/17:08
       */
      
      public class Client {
          public static void main(String[] args) {
              // 耦合
              IAccountService as = new AccountServiceImpl();
              System.out.println(as);
              as.saveAccount();
          }
      }
      

      可以看到,现在程序中表现层与业务层,表现层和持久层出现了耦合,我们应该进行避免,下面采用工厂模式来降低耦合。

    5. 创建一个bean.properties文件

      accountService=com.ben.service.impl.AccountServiceImpl
      accountDao=com.ben.dao.impl.AccountDaoImpl
      
    6. 创建bean对象的工厂,它就是创建我们的service和dao对象的。

      Bean:在计算机英语中,有可重用组件的含义。

      JavaBean:用java语言编写的可重用组件。
      javabean > 实体类

      1. 需要一个配置文件来配置我们的service和dao配置的内容:唯一标识=全限定类名(key=value);
      2. 通过读取配置文件中配置的内容,反射创建对象。配置文件可以是xml也可以是properties(Spring框架中使用的是xml文件),在本次案例中我们使用properties。
      /**
       * @ClassName: BeanFactory
       * @author: benjamin
       * @version: 1.0
       * @description: bean工厂
       * @createTime: 2019/07/24/17:08
       */
      
      public class BeanFactory {
      
          //定义一个Properties对象
          private static Properties props;
      
          //定义一个Map,用于存放我们要创建的对象。我们把它称之为容器
          private static Map<String, Object> beans;
      
          //使用静态代码块为Properties对象赋值
          static{
              try {
                  //实例化对象
                  props = new Properties();
                  //获取properties文件的流对象
                  InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
                  props.load(in);
                  //实例化容器
                  beans = new HashMap<String,Object>();
                  //取出配置文件中所有的Key
                  Enumeration keys = props.keys();
                  //遍历枚举
                  while (keys.hasMoreElements()){
                      //取出每个Key
                      String key = keys.nextElement().toString();
                      //根据key获取value
                      String beanPath = props.getProperty(key);
                      //反射创建对象
                      Object value = Class.forName(beanPath).newInstance();
                      //把key和value存入容器中
                      beans.put(key,value);
                  }
              }catch(Exception e){
                  throw new ExceptionInInitializerError("初始化properties失败!");
              }
          }
      
          /**
           * 根据bean的名称获取对象
           * @param beanName
           * @return Object
           */
          public static Object getBean(String beanName){
              return beans.get(beanName);
          }
      }
      
    7. 修改表现层文件

      public class Client {
          public static void main(String[] args) {
      
              for(int i=0;i<5;i++) {
                  IAccountService as = (IAccountService) BeanFactory.getBean("accountService");
                  System.out.println(as);
                  as.saveAccount();
              }
          }
      }
      
  • 相关阅读:
    String、StringBuilder、StringBuffer区别
    深拷贝和浅拷贝
    二叉查找树(一)
    二叉树的遍历
    二叉树
    递归
    队列

    数据结构基础
    视图
  • 原文地址:https://www.cnblogs.com/benjieqiang/p/11238356.html
Copyright © 2011-2022 走看看