java之浅谈类与类之间的解耦(Spring前言)

时间:2024-04-07 18:21:07

类与类之间的解耦

我们在学习Spring Framework之前首先弄明白什么是
耦合:耦合就是一个事务需要完成一件事情,就必须使用/依赖另外一个事务。这就是耦合。通俗地举个例子:一个男人结婚后只能与他老婆XXOO,这时男人就会被他老婆耦合了,这种属于高耦合哈。这就是耦合哈;那么大概了解耦合的概念了吧。
解耦了解耦合之后,我们再来聊聊什么是解耦。猜你也应该知道大概了。没错,就是一个男人在没结婚之前可以与多个不同的女子XXOO,那么这个男人想要做的这件事情就不会局限于婚后的老婆了。这就是解耦。
废话不多说,上代码演示就一幕了然了。
首先我们有一个已婚男人类,他想XXOO那么就需要他的老婆来完成这件事情。
java之浅谈类与类之间的解耦(Spring前言)
java之浅谈类与类之间的解耦(Spring前言)
仔细看这里的男人类,他想完成这件事情必须new一个老婆对象出来,然后调用他老婆的方法。假设他老婆类没了,编译都不能通过。而且接收他老婆的类型也是他的老婆类型。这种耦合性特别高。
搞过java数据库连接的朋友都知道,加载驱动的两种方式,一:使用 DriverManager 的 register 方法;(DriverManager.registerDriver(new Driver());)
二:使用Class.forName 的方法;( Class.forName(“com.mysql.jdbc.Driver”);)
第一种方式:我们的类依赖了数据库的具体驱动类(MySQL) ,如果这时候更换了数据库(比如 Oracle) ,
需要修改源码来重新数据库驱动。这显然不是我们想要的。这种方式的前提是你必须先把驱动包导入才可写代码。耦合性高在编译期。如果我们想更换数据库,那么就需要该项目代码,这也的代价很大。
第二种方式:编译不会出错,但是运行时出错,那么就做到了编译解耦。同时,也产生了一个新的问题, mysql 驱动的全限定类名字符串是在 java 类中写死的,一旦要改还是要修改源码。解决这个问题也很简单,使用配置文件配置。当我们需要更换数据库时,只需要换jar包以及更改配置文件的驱动名称即可。

好,我们回到我们的代码,既然出现了高耦合,那么我们就一步一步来解耦。看看最终解耦的结果是什么样的。

首先使用接口部分解耦

  • 使用接口,做到左边解耦;
    怎么做到?首先我们创建一个女人接口类
    java之浅谈类与类之间的解耦(Spring前言)
  • 让wife类实现woman类
    java之浅谈类与类之间的解耦(Spring前言)
  • 男人类就用多态的方式获取老婆,这样只要是女人接口的子实现类就可以创建她,调用她的功能完成快乐。这里做到了左边部分解耦,等号的左边不需要变,右边只要实现了女人类的类就可以接收它的对象。
    java之浅谈类与类之间的解耦(Spring前言)

总结

  • 优点: 耦合度相对原始方式 减低了一点;
  • 缺点: 多写了接口, 还是需要改源码 不好维护

在接口部分解耦基础上使用工厂解耦

  • 1:Woman接口不变
  • 2:Wife实现类不变
  • 3:添加制造女人的静态工厂(负责创建指定名字的女人),工厂使用反射来创建对象而不是使用new语法创建对象,这工厂也做到了解耦。
    java之浅谈类与类之间的解耦(Spring前言)
  • 4:男人类不再自己new女人对象了,而实告诉工厂我要那个女人名字,你给我造一个出来。哈哈,譬如说:我要(苍老师/波老师/小野老师)。名字传参的方式传入工厂。
    java之浅谈类与类之间的解耦(Spring前言)

总结:

  • 1优点:男人类里面不再需要new了,看到没?不再用new这个语法了。解耦越来越靠近了。只需要告诉工厂一个女人名字就可以得到一个女人对象。
  • 2缺点:用起来感觉不错,其实不然,我们看看男人类里面使用工厂创建女人对象的时候还要指定告诉工厂女人名字,这个名字可是要全限定名啊,换句话说,【地球.日本.女优.波老师】是这也的一个全限定名。写的台死了。我们是不是想用波老师这也的参数就可以了?有的是办法只要你想得到。
    java之浅谈类与类之间的解耦(Spring前言)

在工厂模式下使用配置文件解决代码的字符串硬编码问题!

  • 1:首先我们将男人类里面调用女人工厂的参数配置到xml配置文件中。文件名:applicationContext.xml
    java之浅谈类与类之间的解耦(Spring前言)
  • 2:接口类不变
  • 3:实现类不变
  • 4:男人类调用工厂获取女人的方法传参改变
    java之浅谈类与类之间的解耦(Spring前言)
  • 5:关键的是工厂代码。工厂里面的getWomanFactory()方法里面需要加载配置文件,获取配置文件里面的所有标签,然后比对id属性的值是否是外部传入的值,如果是,则获取对应的class属性的值,通过class属性的值创建对象返回给外部调用者。
    java之浅谈类与类之间的解耦(Spring前言)

总结:

  • 优点:类与类之间实现了解耦(在类中不再出现new语法,即使删除了wife实现类,也不会影响代码的编写。即使是更换了实现类,我们也不用该动代码,只需要修改配置文件即可。是不是很方便了?男人类中调用静态女人工厂的时候传参由类的全限定名到传一个别名id。解决了字符串硬编码的问题。
  • 缺点:做到这里确实是实现了解耦。其实解耦也就这么回事。解耦 =(接口+实现类+工厂+配置文件)。但是我们发现了一些性能问题。男人每次调用静态女人工厂的时候,都会去读取配置文件。这似乎非常地浪费资源。别急,只要我们能想到这些问题就是进步了。有问题就从来不缺解决问题的方案。

解耦基础上优化性能

1:接口不变
2:实现类不变
3:男人类不变
4:工厂类改变(我们可以将读取配置文件的方式放到静态代码块里面,将读取出来的数据再用一个Map全局容器来存储。这样以后男人类调用静态女人工厂的时候就不需要每次都去加载配置文件,而浪费资源。后面工厂类直接从Map容器中拿出id进行比对传入的id值,如果对上了那么就取出class属性,创建对象返回给调用者即可)
java之浅谈类与类之间的解耦(Spring前言)
java之浅谈类与类之间的解耦(Spring前言)

总结:

  • 优点:配置文件全局只需加载一次,性能提高。
  • 缺点:我们发现,男人类每次调用getWomanFactory()方法,静态女人工厂都会创建一个新的对象,如果我每次都想找波老师,似乎每次都要创建一个新的波老师给我。这样跟同一个波老师没啥区别。功能都一样。其实很多时候我们编码都不建议频繁的创建相同的对象调用相同的方法。我们只需要创建一次这个对象,多次调用这个对象的这个方法即可。这样也可以降低资源的开销。没错,只要你能想到这些问题,那么你就是在思想上的进步。

配置文件性能优化基础上使用单例模式提高性能

  • 1:接口类不变
  • 2:接口实现类不变
  • 3:男人类不变
  • 4:静态女人工厂类改变(我们试想一下,怎么样才能实现单例模式?实现单例模式有那些方案?什么样的类适合使用单例?好分析一下

什么样的类适合使用单例?

  • 一个类中只有方法调用。这样的类就适合使用单例。譬如说:我们用到的一些工具类,工厂类等。

实现单例模式有那些方案?

  • 1:注册式单例(程序运行时只创建一次该类对象)
  • 2:改变类结构式单例(懒汉、饿汉、双重检测、静态内部类、枚举等等)

分析后发现使用注册式单例是符合本次需求的

优化后的静态女人工厂代码为如下:
java之浅谈类与类之间的解耦(Spring前言)
java之浅谈类与类之间的解耦(Spring前言)

总结:

  • 优点:完全解耦+提供性能+节省空间
  • 缺点:无
    聊到这里,如果使用过Spring的朋友,一眼就可以看出来这里的前因后果,没错这里采用了Spring的IOC思想进行解耦。IOC:控制反转。就是将创建对象的权力交给工厂(Spring用的工厂是:BeanFactory),创建出来的对象放到一个全局容器中(Spring用的全局容器是ClassPathXmlApplicationContext等有好几个的),使用者只需要进行配置,将要创建的对象的全路径名和id告诉Spring的配置文件applicationContext.xml,Spring会在加载时读取配置文件,反射创建你所配置的对象存储到全局容器中,这时候,你就可以通过BeanFactory的getBean()方法获取你想要的对象啦。

END…