`
czx566
  • 浏览: 3589 次
  • 性别: Icon_minigender_1
  • 来自: 未来
最近访客 更多访客>>
社区版块
存档分类
最新评论

小样,在胡说3

阅读更多
   在上一篇博文中中,我似乎彻底的否定了IOC模式的效用,毕竟那种丑陋的代码对于有完美主义倾向的程序员来说,的确是越看越难受。
    但后来,我在je论坛里学习了关于领域模型的讨论,突然有一种山重水复疑无路,柳暗花明又一村的感觉。原来我一直采用的开发模型是一种贫血模型,数据只是一种哑数据。因此原来的service和dao都是一种过程调用,于是就会出现在service中,会依赖很多dao
接口的问题。
    那么采用了领域模型,则更加的面向对象,代码的可读性和可测性将大大的提高。
    对于service层的代码,我认为既是一个过程调用代码,一般而言,对于service暴露的服务方法,我们必须首先将其降解为一步一步过程,而过程中调用的元素就是领域模型,而service层中必然存在的是服务的一个过程的代码描述,这也是service层存在的意义,而在这个过程代码描述中,如果我们教科书一样的利用依赖注入,将过程中产生的过程变量(既局部变量)必须全部依赖IOC的注入,这样丑陋的代码就生成了!一个个本来就是局部变量的对象,变成了类变量~完全违背了IOC的初衷!
    那么在过程代码中,我依然认为:工厂模式才是最合适的!你需要什么,我就给你造什么,用完了,我就可以回收。这样我既降低了对象的生命周期,也减少了过程方法的依赖(上篇提到真正的业务方法,必须依赖setDAO的准确调用)。
   那么IOC是否彻底没用了,不,我觉得IOC应该是领域模型中使用的。在领域模型中,我认为在service过程代码中最基本的操作元素就是领域模型,上面说的过程则是调用领域模型的编排过程。而针对领域模型的产生和其方法中依赖其他类型的对象,则应该彻底交给IOC容器去控制,也就是利用IOC去注入领域模型需要的其他对象。
    举一个生活的例子:
   
    你去买电脑,那么卖电脑就是一个service服务,

   那么按照传统的丑陋的spring IOC应用模式就成了
  
  public class 电脑商城 {

          private 电脑组装商户 a;
  private 主板商户 b;
 
  private 显示器商户 c; 

          private 物流  d;
  ......
 
 
  public void 卖电脑(){
      主板 技嘉主板 = b.给你主板();
      显示器 DEll = c.给你显示器();  
      ...
              a.组装(..);
              d.送货(..)   
  }
  
}

对应的xml配置文件为:
   <bean id = "电服脑商城务" class = "电脑商城"> 
     <property name="a" ref="电脑组装商户" /> 
     <property name="b" ref="主板商户" /> 
     <property name="c" ref="显示器商户" /> 
     <property name="d" ref="物流" /> 
   </bean> 


   那么我在调用这个服务前,我必须先利用IOC注入那么多其他商户~~,只要电脑商城不下班不消亡,那么你这些其他商户就不能跑~~,多么霸道的逻辑。而且在编写xml配置文件时,你会明显感觉:我在编写的是一个电服脑商城务对象的具体实现,而我不应该关注这个对象到底实现了那些服务,我为什么要将那么多的property 注入到这个对象里面?


  那么如果采用领域模型和有边界的IOC

  那么就变为

   public class 电脑商城 {

  private 商户工厂  factory;
  private 物流  d;
 
  public void  卖电脑(){
    
       主板商户 b =  factory.getBean("主板商户");
       主板 技嘉主板 = b.给你主板();
       显示器商户 c =  factory.getBean("显示器商户");
       显示器 DEll = c.给你显示器();  
       ...
                电脑组装商户 a =  factory.getBean("电脑组装商户");
               a.组装(..);                    
               d.送货(..);  
  }
  
  }
而此时对应的xml文件则是
  <bean id = "电服脑商城务" class = "电脑商城"> 
     <property name="factory" ref="商户工厂" /> 
     <property name="d" ref="物流" /> 
   </bean> 

那么 IOC所关注的是这个商城必须依赖的条件:商户工厂,和物流,这是商场服务的一部分,所以他们应该和商城共进退。那么我在编写xml文件中,我就很好的能理解这个商城是肯定有一个呼叫商户的大喇叭 和一个全天恭候的物流,而我无须关注这个商城到底提供了那些具体的服务。

    而调用别人商户彩用的工厂模式,就类似于商城的大喇叭,我需要你的时候你就来,别的时候你可以不来。 那么 在大喇叭呼叫某一个具体商户时,可能此商户还需要依赖其他商户,那么此时也应该利用IOC容器去注入,有点感觉像商户之间的协定了。而这个对于商城是无须关心的。


分享到:
评论
8 楼 moonranger 2009-01-15  
怎么在领域模型中IOC?实在想请教一下……
别告诉我是factory.getBean("xxxx")这样的,这个,我觉得依然是工厂,不是IOC。
真正用好了IOC的系统,factory.getBean("xxxx")这样的代码仅仅存在于很少很少的几个地方,对象之间的依赖关系都由容器妥当地管理好了。
7 楼 wq163 2009-01-05  
我觉得说得有道理,除了lz说得以外,我碰到过其他很多情况下如果一概使用IOC的确很丑陋
6 楼 czx566 2008-12-18  
如果
dongwenhua 写道

czx566 写道
刚刚我又考虑你的话,我得出的观点和你恰恰相反。&nbsp;&nbsp;&nbsp; 如果在业务设计划分时,如果将业务划分过细,比如只有一个表对象增删改查,那么就不会出现我所描述的情况,因为你一个业务依赖很少甚至一个DAO,那么理解起来的确很简单。但是这种过细的业务划分,那么service层的业务方法是不是显得过于单薄和重复? 而且会大大加大了view层的负担!&nbsp;&nbsp;&nbsp; 特别如果出现更为复杂的逻辑,太细的粒度业务划分会造成service层代码的层次的模糊性!如果业务方法简单的话,例如只是简单的CRUD,Service几乎是DAO的一个代理的话,就会有重复的臭味道,这样通常会做大粒度的Facade


你所说的Facade模式,就是我认为的粗粒度service接口,
因为在三层结构里,facade的也应该属于service层的逻辑,
所以你说的facade无外乎就是一个更加粗粒度的service接口,
那么恰恰在这种粗粒度的service中,如果你过多地依赖其它对象,
就很有可能会形成丑陋的代码!
5 楼 dongwenhua 2008-12-17  
czx566 写道

刚刚我又考虑你的话,我得出的观点和你恰恰相反。
    如果在业务设计划分时,如果将业务划分过细,比如只有一个表对象增删改查,那么就不会出现我所描述的情况,因为你一个业务依赖很少甚至一个DAO,那么理解起来的确很简单。但是这种过细的业务划分,那么service层的业务方法是不是显得过于单薄和重复? 而且会大大加大了view层的负担!
    特别如果出现更为复杂的逻辑,太细的粒度业务划分会造成service层代码的层次的模糊性!

如果业务方法简单的话,例如只是简单的CRUD,Service几乎是DAO的一个代理的话,
就会有重复的臭味道,这样通常会做大粒度的Facade
4 楼 czx566 2008-12-17  
dongwenhua 写道

我看了楼主指责Spring的两篇文章,我感觉楼主一直对局部变量存有偏爱,以至于能用局部变量的地方,如果用了成员变量(博主所说的“类变量”当然是欠妥的),就会认为是一种丑陋的代码,以至于彻底否定了IOC的作用。 虽然尽量使用局部变量是一个好的习惯,但是我觉得使用这个观点来否定IOC是欠妥的,Service层依赖与DAO,这种依赖关系通过注入方式来管理,是非常合理的,并且DAO作为属性注入也是合理的:首先、通常依赖的DAO会在Service的多个方法中使用。即使现在在一个方法中使用,如果作为局部变量使用工厂创建,随着Service发展,很可能需要另外的功能,而实现这个功能的方法可能使用这个DAO,最终的结果还是重构为一个属性。其次、DAO作为属性注入,方便单元测试。你可以注入一个MockDao来测试Service,而如果作为一个局部变量,很难去做单元测试。 IOC的真正效力在于翻转控制,让容器自动管理和装配受管的对象,你拿出来的对象就是可用的了,不需要更多的胶水代码去组装粘合对象 了,他同时在倡导针对接口编程,最终产生的是可插拔的松耦合的系统。博主所说的手工创建一大堆工厂,其实在说提倡在代码中使用Spring的factory.getObject("beanName"),这样完全丧失了IOC的真正优点。工厂和依赖注入比只能显得丑陋而不是优雅。 博主文章所举的例子在领域模型中包含业务方法,是很优雅的。但实际往往没有例子那么简单,许多业务方法是和多个领域模型相关的,这种情况下把业务方法放到Service可能会闲得更自然。贫血型未必很差,虽然在面向对象方法学上来讲的确有一定的问题,但是它是一种很好的解耦方式,充血型可能对导致领域对象之间更紧的耦合度,需求变化的时候具有更多的不稳定性。

刚刚我又考虑你的话,我得出的观点和你恰恰相反。
    如果在业务设计划分时,如果将业务划分过细,比如只有一个表对象增删改查,那么就不会出现我所描述的情况,因为你一个业务依赖很少甚至一个DAO,那么理解起来的确很简单。但是这种过细的业务划分,那么service层的业务方法是不是显得过于单薄和重复? 而且会大大加大了view层的负担!
    特别如果出现更为复杂的逻辑,太细的粒度业务划分会造成service层代码的层次的模糊性!

3 楼 czx566 2008-12-17  
dongwenhua 写道

我看了楼主指责Spring的两篇文章,我感觉楼主一直对局部变量存有偏爱,以至于能用局部变量的地方,如果用了成员变量(博主所说的“类变量”当然是欠妥的),就会认为是一种丑陋的代码,以至于彻底否定了IOC的作用。 虽然尽量使用局部变量是一个好的习惯,但是我觉得使用这个观点来否定IOC是欠妥的,Service层依赖与DAO,这种依赖关系通过注入方式来管理,是非常合理的,并且DAO作为属性注入也是合理的:首先、通常依赖的DAO会在Service的多个方法中使用。即使现在在一个方法中使用,如果作为局部变量使用工厂创建,随着Service发展,很可能需要另外的功能,而实现这个功能的方法可能使用这个DAO,最终的结果还是重构为一个属性。其次、DAO作为属性注入,方便单元测试。你可以注入一个MockDao来测试Service,而如果作为一个局部变量,很难去做单元测试。 IOC的真正效力在于翻转控制,让容器自动管理和装配受管的对象,你拿出来的对象就是可用的了,不需要更多的胶水代码去组装粘合对象 了,他同时在倡导针对接口编程,最终产生的是可插拔的松耦合的系统。博主所说的手工创建一大堆工厂,其实在说提倡在代码中使用Spring的factory.getObject("beanName"),这样完全丧失了IOC的真正优点。工厂和依赖注入比只能显得丑陋而不是优雅。 博主文章所举的例子在领域模型中包含业务方法,是很优雅的。但实际往往没有例子那么简单,许多业务方法是和多个领域模型相关的,这种情况下把业务方法放到Service可能会闲得更自然。贫血型未必很差,虽然在面向对象方法学上来讲的确有一定的问题,但是它是一种很好的解耦方式,充血型可能对导致领域对象之间更紧的耦合度,需求变化的时候具有更多的不稳定性。


在这篇文章中我没有彻底否定IOC,不过我在上一篇彻底否定了(现在证明我错了),我现在的观点是IOC是有边界的,不应该在三层中都存在,应该只存在于领域模型那层!当然你可以认为我偏执~呵呵
2 楼 dongwenhua 2008-12-17  
我看了楼主指责Spring的两篇文章,我感觉楼主一直对局部变量存有偏爱,以至于能用局部变量的地方,如果用了成员变量(博主所说的“类变量”当然是欠妥的),就会认为是一种丑陋的代码,以至于彻底否定了IOC的作用。
虽然尽量使用局部变量是一个好的习惯,但是我觉得使用这个观点来否定IOC是欠妥的,Service层依赖与DAO,这种依赖关系通过注入方式来管理,是非常合理的,并且DAO作为属性注入也是合理的:首先、通常依赖的DAO会在Service的多个方法中使用。即使现在在一个方法中使用,如果作为局部变量使用工厂创建,随着Service发展,很可能需要另外的功能,而实现这个功能的方法可能使用这个DAO,最终的结果还是重构为一个属性。其次、DAO作为属性注入,方便单元测试。你可以注入一个MockDao来测试Service,而如果作为一个局部变量,很难去做单元测试。
IOC的真正效力在于翻转控制,让容器自动管理和装配受管的对象,你拿出来的对象就是可用的了,不需要更多的胶水代码去组装粘合对象 了,他同时在倡导针对接口编程,最终产生的是可插拔的松耦合的系统。博主所说的手工创建一大堆工厂,其实在说提倡在代码中使用Spring的factory.getObject("beanName"),这样完全丧失了IOC的真正优点。工厂和依赖注入比只能显得丑陋而不是优雅。
博主文章所举的例子在领域模型中包含业务方法,是很优雅的。但实际往往没有例子那么简单,许多业务方法是和多个领域模型相关的,这种情况下把业务方法放到Service可能会闲得更自然。贫血型未必很差,虽然在面向对象方法学上来讲的确有一定的问题,但是它是一种很好的解耦方式,充血型可能对导致领域对象之间更紧的耦合度,需求变化的时候具有更多的不稳定性。
1 楼 hypercube1024 2008-12-17  
老大,域模型的生命周期是由持久层处理的,你想在域模型里面注入的话,需要用到静态织入等更方法,而且,域模型是包括 实体,服务,值对象,仓库,工厂等等的

相关推荐

    飞腾小样列表插件

    风华小样列表窗软件是由风华软件工作室开发,面向方正飞腾3.1排版软件使用的小样列表插件。实现了排版小样的列表功能。可以一次将所有的文字和图片小样纳入小样列表窗中,排版时,将小样拖到版面上,自动形成分区。...

    网站ps小样模版

    网站PS小样模版是一种设计预览,通常用于展示网页设计的概念和布局,帮助客户或开发者在实际开发前理解设计的视觉效果。这种模版基于Adobe Photoshop(简称PS)创建,这是一种广泛使用的图像处理和图形设计软件。在...

    jsp代码小样

    **JSP(Java Server Pages)** 是一种动态网页技术,由Sun Microsystems开发,现在由Oracle公司维护。它允许Web开发者将HTML代码与Java..."jsp代码小样"可能就是这样一个简单的JSP页面,展示如何在实际项目中使用JSP。

    在unity 中使用XML的小样

    在Unity游戏开发中,XML(eXtensible Markup Language)是一种常见的数据存储格式,用于保存结构化数据。XML文件易于阅读和编写,并且可以被多种编程语言解析,包括C#,这在Unity中广泛用于配置文件、游戏设置、角色...

    雨篷小样图

    天津市西青区王稳庄镇农民安置房幼儿园雨篷小样图

    迁移学习模型下的小样本人脸识别算法.pdf

    【迁移学习】在小样本人脸识别中的应用至关重要,因为传统的人脸识别系统往往依赖于大量标记的数据,但在实际情况下,获取大量标注的人脸数据并不总是可能的。迁移学习提供了一种解决方案,它允许模型从已有的大规模...

    EXT测试小样例--EXT测试小样例

    EXT测试小样例主要目的是验证EXT Grid在实际应用中的性能、稳定性和功能完备性。这可能包括单元测试、集成测试和系统测试,确保在不同场景下EXT Grid都能正常工作。测试可能涵盖以下几个方面: 1. 功能测试:检查...

    OPENGL小样·

    关于图像处理的demo,一些基本函数的应用

    大师谈秘诀——游戏场景小样设定

    姜波在中国游戏行业有着20年的丰富经验,参与制作了多款成功的网络游戏如《天骄3》和《天骄2》,并且在行业内培养了许多优秀的游戏美术主管和设计师,因此他在游戏行业内备受尊敬,被誉为“设计师导师”。...

    论文研究-基于小样本集弱学习规则的KNN分类算法.pdf

    基于小样本弱学习规则的KNN分类算法旨在提高基于小样本集的KNN算法的分类精度,它首先对Dl中的数据对象进行学习,从中选取一些数据,利用学到的标签知识对其进行类别标号,然后将其加入到Dl中;最后利用扩展后的Dl对...

    此工具可以将方正小样文件转换成网页文件。特点是可以将方正表格注解转换成网页格式

    此工具是用VB6精简版编写的。可以将方正书版小样文件转换成网页文件,特点是可以将表格注解转换成网页格式。因是给单位定制的,所以并不是支持所有的注解命令。

    kitti数据集小样

    在我们得到的“数据小样”中,虽然可能只是完整数据集的一部分,但仍然包含了一些关键组件,如图像和LiDAR数据,这为我们了解和实践Kitti数据集提供了宝贵的起点。 Kitti数据集分为多个子任务,其中最为知名的包括...

    jquery插件使用小样大全

    3. **插件方法**:许多插件提供了一系列方法供你在运行时操作,如开启、关闭、设置选项等。这些方法通常可以通过实例对象调用,如`$("#element").pluginName("methodName", arg1, arg2)`。 4. **插件事件**:插件...

    springboot2.2.0重构旧岛小样koa2微信小程序服务端.zip

    微信小程序是腾讯公司基于微信平台推出的一种轻量级应用形态,它无需用户下载安装即可在微信内直接使用。自2017年正式上线以来,小程序凭借其便捷性、易获取性和出色的用户体验迅速获得市场认可,并成为连接线上线下...

    基于深度学习算法的小样本人耳识别.pdf

    在本文中,作者提出了基于深度学习算法的小样本人耳识别方法,该方法可以解决小样本问题和姿态变化等问题。 人耳识别(Ear Recognition)是生物识别技术中的一种常用方法,它可以用于身份识别和身份验证。然而,人...

    基于ssm彩妆小样售卖商城.zip

    - **毕业设计**:这表明这是一个学生在毕业前完成的综合性项目,旨在展示其在软件开发方面的技能和理解。 - **Java**:该项目的核心编程语言,Java是后端开发的常用语言,尤其适合大型企业级应用。 - **springboot**...

    QML中渐变控件小样例

    QML中渐变控件小样例

    Login登录页面小样

    3. 提示信息:合理使用提示信息,如placeholder属性可以在输入框内显示默认提示文字,帮助用户理解应输入什么内容。例如:`请输入用户名"&gt;`。 4. 错误处理:当用户输入的信息无效或不匹配时,需要有明确的错误提示...

    ssm073彩妆小样售卖商城的设计与实现+jsp.zip

    3. 彩妆电商:专注于彩妆小样的在线销售,属于垂直领域的电商应用。 4. 数据库管理:可能使用MySQL或其他关系型数据库,存储商品信息、用户数据等。 【压缩包子文件的文件名称列表】: 1. 论文.docx:这可能包含了...

Global site tag (gtag.js) - Google Analytics