IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> IOC容器逻辑上如何解耦 -> 正文阅读

[系统运维]IOC容器逻辑上如何解耦

????????初学SpringIOC容器,我们对于解耦可能还是处于一个相对抽象的概念理解,后面作者也是查找了一些资料,本片文章就用一个例子来说明IOC容器解耦的妙处

????????假设现在公司需要完成一个与新闻公司的合作项目,项目需要与新闻社进行合作,获取新闻社的新闻并且存储到我们的数据库中,用于展示。

????????我们可以分析一下:当有新的新闻时,通过我们设计的程序,定时的到指定的新闻服务器下,去抓取最新的新闻,然后将这些新闻在通过指定的程序存储到我们的数据库中。因此整个处理过程就分为两大块:1.抓取新闻2.存储新闻

????????我们定义两个接口,用于规范两大业务功能,其中Listener接口用于处理抓取新闻的功能,Persistener用于处理存储新闻的功能。

public interface Listenener {
    Object getNews1();
    Object getNews2();
????????...
}
public interface Persistener {
    void saveNews1(Object news);
    void saveNews2(Object news);
????????...
}

????????之后提供了一个Provider类去处理整个新闻的整体流程

public class Provider {
    private Listenener listenener;
    private Persistener persistener;

    public void handleNews(){
        Object news1 = listenener.getNews1();
        Object news2 = listenener.getNews2();
????????????????...
        persistener.saveNews1(news1);
        persistener.saveNews2(news2);
????????????????...
    }
}

????????到此我们已经可以感受到整个流程了,我们看Provider可以发现,代码可以实现正常的运行逻辑,但是两个属性都是null,而两者又是接口,无法new出对象,所以需要实现类去注入对象。

????????此时有一家新闻社A宣布与我们合作,我们派员工针对与他们的新闻服务器数据设计了AListener和APersistener两个实现类,分别用于抓取A新闻社的时事新闻,和将抓取的内容存储到数据库两个具体功能。

????????如果不使用IOC容器,那么一般情况下我们就会直接在Provider的handleNews方法中直接new出两个实现类对象。

import ...AListenener;
import ...Apersistener;

public class Provider {
    private Listenener listenener;
    private Persistener persistener;

    public void handleNews(){
????????listenener = new AListenener();
????????persistener = new Apersistener();
        Object news1 = listenener.getNews1();
        Object news2 = listenener.getNews2();
????????????????...
        persistener.saveNews1(news1);
        persistener.saveNews2(news2);
????????????????...????????
    }
}

????????如上,Provider类无意间就引入了两个包,Provider与AListener还有APersistener的耦合性上升了,这三个类开始绑定在一起。

? ? ? ? 此时,无论我们在何时何地创建Provider对象,调用方法时都将在Provider类导入AListener和APersistener类的包,创建对应的对象。(这里留个问题1,在文章末尾解答,读完文章后再回来看此处的问题

????????如此运行是完全没有逻辑上的问题,但是这时,B新闻社决定与我们合作,公司派员工写了用于从B新闻服务器抓取时事新闻的BListener实现类。当公司打算派人实现接口Persistener时,领导顿住了。咦,我这不是还有一个专门存储数据用的APersistener类吗?那还浪费钱去重新做一个干什么。(由于抓取新闻的功能都由Listener接口去约束,所以无论实现类如何书写,返回值都是一样的,对于一样处理好的数据,同一个Persistener就可以处理)。那么领导就开始思考,既然APersistener能用,那我干脆就还是用Provider处理与B社的合作吧。

? ? ? ? 现在问题来了,Provider已经与AListener绑定在一块了,项目已经投入使用了,现在再去修改源码,也免不了成本,假设你有时间,不怕麻烦终于修改了源码,这时候突然又来了一家新闻社C,那咱们继续花时间修改源码吗?现在我们只与一家A合作,当我们与十家合作时,再去修改源码就相当的麻烦, 时间就是小钱钱。有没有一种方法,不是我们手动修改源码主动的给Provider提供属性,而是当Provider需要AListener时就提供给他AListener对象,需要BListener时就提供给他BListener对象呢?

? ? ? ? 这时IOC容器默默的举起了手,通过IOC容器读取配置文件的方法,我们只需要将AListener,BListener对象提前创建好,存放到一个容器中,当创建Provider对象时看需要哪个,那就拿走哪个。

? ? ? ? 我们在很多地方可能都需要导入一些包,去完成对象的创建,依赖分散在各处,那么耦合就分散在各处,最后可能整个项目牵一发而动全身。一处没完成,处处等。一处报错,处处有罪。项目流程的进行与中间的测试变得异常困难。正如一句话:原子弹下无冤魂。当我们使用IOC容器使控制权反转后,联系就不会在一件事的不同时间点出现,出现一件解决一件,而是从一开始就把解决问题的答案放在搜题软件里,需要哪个搜哪个,没有哪个配置哪个,然后提供哪个。

问题1:这时可能就要有人来问了,那为什么非要在方法中给两个属性赋值呢,我们在创建Provider对象时干脆直接用set方法赋值,或者含参构造器给这两个属性赋值,Provider不就不用导入两个包了吗?这样Provider与这两个类的耦合性不就降低了吗?

? ? ? ? 这样想确实没有问题,Provider与这两个类的耦合性确实降低了。我们在获取Provider对象时就直接给参数赋值,那么Provider类中就完全不需要导入AListener或者BListener的包了,这么一想,我们的IOC容器好像还是多余的设计,我们只需要在获取Provider对象时根据需要给属性赋值,那不就行了吗?

Provider provider = new Provider(new AListenener(),new APersistener());
Provider provider = new Provider(new BListenener(),new APersistener());

? ? ? ? 这么想就大错特错了,我们最终处理问题时,需要创建Provider对象,调用Provider中的方法,那么我们处理问题的类就不需要导入AListenener的包,或者导入BListenener的包了吗?当然不可能。我们回到最初,我们为什么需要Provider对象,就是因为Provider对象能解决问题。无论我们用哪个类最终处理转移新闻这个目的,我们都需要自己手动在代码中创建对象,无论对象拖到哪创建,都最终有一个地方需要我们手动创建对象。一旦创建对象那么就需要导入相关包,创建联系,而联系一旦在类与类之间存在,就不方便修改。所以我们需要一个人,去处理联系,这个人就是IOC。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 23:28:17  更:2022-01-29 23:28:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 8:33:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码