文档章节

容器,对象生命周期管理的基石

FansUnion
 FansUnion
发布于 2015/10/22 10:29
字数 2321
阅读 4
收藏 0
点赞 0
评论 0
郑重申明:包括本文在内的很多技术文章,大多出自山外高人,而非Fans。
Fans暂时没有能力写作优秀的技术文章,Fans只是转载、浓缩、加入部分自己的代码而已。

 
           对象的生命周期管理在基于面向对象的编程语言中是一个永恒的话题。从语法上讲,面向对象的高级编程语言都是以“对象”为中心的。而对象之间的继承关系、嵌套引用关系所形成的对象树结构为我们进行对象级别的逻辑操作提供了足够的语法支持。但这样一来,对象之间所形成的复杂关系也为对象生命周期管理带来了问题:
 
         在程序的运行期,应如何创建我们所需要的对象?
       当创建一个新的对象时,如何保证与这个对象所关联的依赖关系(其依赖对象)也能够被正确地创建出来?
 
       这两大问题不仅是面向对象的编程语言中的核心问题,也是每个框架在进行设计时必须越过的坎。业界对于这样的问题也早有公论:
       结论 为了更好地管理对象的生命周期,我们有必要在程序逻辑中引入一个额外的编程元素,这个元素就是容器(Container)。
 

  1.对象的生命周期管理

   两大问题实际上涵盖了对象生命周期管理的两个方面:
  在程序的运行期,对象实例的创建和引用机制。
  对象与其关联对象的依赖关系的处理机制。
 
  为了帮助大家更好地对这两大方面进行解读,我们在这里引入一个非常重要的概念:控制反转(Inversion of Control)。
 
     控制反转是对象生命周期管理中的一个核心概念,由软件大师××提出,并以此为基础创造了一个大家更为熟悉和理解的概念:依赖注入。
 
     那么什么是控制反转呢?在使用基于面向对象的编程语言进行开发时,对象的概念是实现业务逻辑的基础核心。而要真正实现一个复杂的业务需求,则离不开多个对象彼此之间的通力协作来共同完成。对象关系模型中写作的真正含义,正是对象通过其依赖对象的帮助,完成其业务逻辑的过程。而动作特性的对象的嵌套引用,是对象之间精诚合作、协作完成业务逻辑的基本途径,也是对象之间形成依赖关系的
根本原因。在这种情况下,每个对象不得不依赖于与其写作的对象(也就是它所依赖的对象)的引用和构建。更加通俗地说:
 
  结论 每个对象自身对于逻辑的执行能力,被其所依赖的对象反向控制了,这也是控制反转的本质含义。
 
      当对象之间的这种依赖关系与运行期对象的构建机制相结合时,情况就会变得更加复杂。因为在对象创建的时候,除了需要考虑这个对象本身作为一个实例的创建过程,还需要考虑与这个对象形成依赖关系的关联对象的实例化过程。前一个过程能够使对象自身的生命周期得到控制和管理;而后一个过程,则保证了程序在运行期的使用不会受到其所依赖的对象的生命周期的限制。

      因此,我们可以看出对象的生命周期管理的两个不同方面的内容是密不可分的。对象的创建是对象依赖关系管理的基础,没有对象的创建过程,其所关联的对象的生命周期也就无从谈起;另外一个方面,如果对象的依赖关系无法被正确处理,那么我们创建出来的依赖对象也就失去了活力,因为它失去了一个对象最为基本的与其它对象协作的能力。
 
2.容器(Container)的引入
     控制反转概念的提出对我们编写程序提出了额外的要求,因为我们不得不去实现“获取依赖对象”这一基本的逻辑功能,从而使得对象与对象之间的协作和沟通变得更为畅通。既然如此,那么如何实现这个获取依赖对象的过程就值得我们仔细掂量。如果这个过程靠程序逻辑自身来实现(也就是说在程序的运行过程中自行管理),那么我们至少可以预见到这种编程模式存在着三大弊端:
 
  对象将频繁创建,效率大大降低(尽管在大多数情况下,这些对象都是无状态的单例对象);
  对象的创建逻辑与业务逻辑代码高度耦合,使得一个对象的逻辑关注度大大分散;
  程序的执行效率大大降低,由于无法区分明确的职责,很难针对对象实现的业务逻辑进行单元测试。
 
  正是看到了这些弊端,业界的软件大师就提出一条“获取依赖对象的过程”的最佳实践:
应该引入一个与具体的业务逻辑完全无关的额外的编程元素容器来帮助进行对象的生命周期管理。
 
  引入容器是以Java为代表的面向对象的编程语言发展过程中的一个重要里程碑。因而,几乎所有的开源框架都有自己的容器实现。甚至有些框架(诸如Spring),更是以容器作为其最核心的基础构建。既然引入容器的目的是为了解决对象生命周期管理中所遇到的问题,那么这一额外的编程元素自身的设计也必须遵循一定的原则:

  容器应该被设计成一个全局的、统一的编程元素。
  这一点几乎无须多做解释。在运行期获取对象实例可能发生在程序的任何一个角落,因此容器作为一个
辅助元素也可能随时在任何地方被调用。这就不得不要求容器对象是一个全局对象。
 
  在最大程度上降低容器对业务逻辑的入侵。
  这是进行容器设计时需要考虑的一个最重要的问题。因为我们引入容器这个额外元素来帮助管理对象生命周期的初衷之一,就是我们希望能够把对象生命周期管理的部分从具体的业务逻辑中提取出来,使得业务逻辑本身能够方便地进行单元测试。
 
  容器应该能够提供简单而全面的对象操作接口。
 引入容器的目的就是为了进行对象操作。因而,简单而全面在这里所表达的意思,一方面是说针对对象的操作接口应该一目了然;另外一个方面,针对对象的操作接口应该涵盖对象生命周期管理的所有内容。

3.容器(Container),不是容器(Collection)

  在Java世界中有一个被称之为Collection的接口,用于表达一组对象的集合。由Collection引申开来的数据结构很多,比如List、Set等。这些接口都是继承自Collection接口,各自表示不同特性的数据结构。从中文翻译的角度,我们习惯把Collection翻译为“容器”,而所有相关的接口及其实现类都被成为“容器结构”。
 
我们在这里引入的容器(Container)的概念与Collection接口所表述的容器概念完全不同。容器(Collection)是一个具体的数据结构类。在容器(Collection)中存储的内容是对象。而容器(Container),却不是一个具体的数据结构类,它用于管理对象的生命周期,我们可以把它看作是一个全局的编程元素。因此,在容器(Container)中,我们将看不到具体的对象存储。整个容器(Container)
从外部看来,就如同是一个可以进行对象操作的工具类。

结论 容器(Container)由一系列对象的操作接口构成,其中应该至少包含获取对象实例以及管理对象之间的依赖关系这两类操作方法。

明确了这一条结论,能够帮助我们对容器(Container)的表现形式有更加深刻的认识,并从中体会到:
          容器的设计原则与引入容器的初衷也是一致的。

 具体的容器(Container)实现,可以参考 Spring框架或者Struts2中容器实现。(*^__^*) 

© 著作权归作者所有

共有 人打赏支持
FansUnion
粉丝 57
博文 858
码字总数 825464
作品 0
丰台
高级程序员

暂无文章

面试宝典-什么是缓存穿透?

缓存穿透是说收到了一个请求,但是该请求缓存里没有,只能去数据库里查询,然后放进缓存。 这里面有两个风险,一个是同时有好多请求访问同一个数据,然后业务系统把这些请求全发到了数据库;...

suyain
11分钟前
0
0
vue基础知识练习2

一、发送AJAX请求 <div id="demo1"><button @click="send">发送AJAX请求</button><button @click="sendGet">GET方式发送AJAX请求</button><button @click="sendPost">POST方式发送A......

一个yuanbeth
13分钟前
0
0
Xamarin Essentials教程磁力计Magnetometer

Xamarin Essentials教程磁力计Magnetometer 磁力计也叫地磁、磁感器,可用于测试磁场强度和方向。在手持设备中,通过磁力计可以计算设备的左右、前后倾斜角度,广泛应用于手机各种的应用中。...

大学霸
18分钟前
0
0
mesos:Authentication timed out

最近当slave开始慢慢部署异地集群的时候又碰上了这个问题 I0717 10:27:11.695762 28852 slave.cpp:895] New master detected at master@192.168.2.161:5050I0717 10:27:11.695811 28852 sl......

xueyi28
24分钟前
0
0
赋予用户库的读写权限

1、创建用户 CREATE USER 'test'@'%' IDENTIFIED BY '15ht46389012t'; #'%' - 所有情况都能访问;‘localhost’ - 本机才能访问;’192.168.1.2‘ - 指定 ip 才能访问 2、赋予权限 grant al...

xixingzhe
25分钟前
0
0
Spring核心——JSR250与资源控制

JSR-175与元编程 要说明JSR-250先要解释清楚JSR-175,要解释清楚JSR就的先了解JCP是什么。网上资料很多,就不细说了,简单的说JCP(Java Community Process)是管理Java生态(包括J2SE、J2E...

随风溜达的向日葵
26分钟前
2
0
Java面试基础篇——第五篇:类的实例化顺序

类的实例化顺序:包括 1.父类静态数据,构造函数,字段;2.子类静态数据,构造函数,字段等, 当我们new一个对象的时候,类实例化的顺序是怎么样的呢? OK.还是上代码比较实在(我就是个实在...

developlee的潇洒人生
27分钟前
0
0
引入mui.css出现闪屏问题

自己写的选项卡切换功能,引入了mui.css样式,当我切换选项卡时,页面会出现闪动,当我把mui.css注释掉后页面就不会出现闪动问题,由于mui.css文件太大,我也不知道什么属性引起的闪屏,所以...

爱喝水的小熊
30分钟前
1
0
大家都在学的编程语言 Python,可以用来干什么?

编者按:Python因为简单全面易用而成为近年来大热的编程语言。但是很多人学习了这门余元的语法和基本功能之后却不知道Python能干什么以及怎么做。Realpython.com上面的一篇文章于是把Python可...

Python燕大侠
46分钟前
2
0
学习大数据必备的5大核心技术,你知道几个?需要掌握哪些知识?

大数据已经成为时代发展的趋势,很多人纷纷选择学习大数据,想要进入大数据行业。大数据技术体系庞大,包括的知识较多,系统的学习大数据可以让你全面掌握大数据技能。学习大数据需要掌握哪些...

董黎明
56分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部