`
jamesby
  • 浏览: 381052 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

关于Service调用Service 的思考

    博客分类:
  • Java
阅读更多
以前做软件都是随便写几个Service,纯粹为了Service而Service,当某天突然发现我的两个Service竟然需要互相访问,于是乎开始考虑如何设计Service,特别是Service之间的依赖关系如何设计的问题,因此偶认为软件Service层的设计应该重点放在两个方面:
一是Service 功能划分的设计;二是Service 与 Service 之间的依赖关系的设计。
其中,Service与Service之间依赖关系的设计又分如下几种:

一是继承关系依赖
    public class ObjectA extends ObjectB{
    }

二是属性关系依赖
    public class OjbectA{
       private ObjectB b;
       public void setB(ObjectB b){
          this.b = b;
       } 
       public void method(){
          b.abc();
       }
    }


三是参数方法参数关系依赖
    public class ObjectA{
       public void method(ObjectB b){
           b.abc();
       }
   }


大家对Spring已经很熟悉了,相信前两种大家用的很多,第三种在开源框架用的比较多.
分享到:
评论
9 楼 jamesby 2007-03-06  
moshalanye 写道
   (个人意见和经验)继承最好不要用,因为偶合性太强,一般依赖关系存在的话的也只能是单向依赖,
尽量将平级的组建在设计的时候就简单设计成为依赖关系的,一但平级的关系变少,组建相互依赖的可能就被最大的降低了(相互依赖形成构造的死循环)。
    同时也最好是定模块的时候把关系比较近的表操作定义在一个模块里面,再在这个模块里在这些表操做的基础上去封装该模块的不同业务service(从而形成有多个service的组建,提供该模块的业务api),每个业务都可以拥有同模块的所有的表操作对象作为DB功能对象(DAO对象实现),这样做就可以利用DAO层和业务层减少平级的依赖。
    当然在这种情况下还是会出现依赖,但这个时候的依赖就是组建的依赖问题了,基础组建(例如对多个关于员工的表提取各种不同的员工信息的组建,log组建,email组建,总之是经常会被很多模块用到对于项目很通用的通用模块组建)被级别更高更上层的组建所依赖,并形成新的功能组建,这样一来依赖关系变的清晰。
恩,在一般的设计中几乎也就用到这些,依赖取决于该组建的通用性,象楼上说的邮件,log等可能是比较通用的,还有例如目前我的系统中有寻呼系统,短信系统,这些可能都是被依赖的Service,如果在一个系统中有这些功能,可以简单的设计他们的依赖关系,如果是多个系统都有类似功能,怎么办?

一是将这些被依赖的东西打包成一个通用的组件,
二是将其设计成一个通用的服务,如通过EJB或者webservice实现.

但是问题扩展成如下程度就好了,比如我设计的是一个简单的框架,与数据库什么的都没有关系,也没有什么所谓的Service,如spring的代码.

这时候在设计的时候怎么考虑对象之间的各种依赖关系.当然这个问题好象很大.


8 楼 moshalanye 2007-03-06  
   (个人意见和经验)继承最好不要用,因为偶合性太强,一般依赖关系存在的话的也只能是单向依赖,
尽量将平级的组建在设计的时候就简单设计成为依赖关系的,一但平级的关系变少,组建相互依赖的可能就被最大的降低了(相互依赖形成构造的死循环)。
    同时也最好是定模块的时候把关系比较近的表操作定义在一个模块里面,再在这个模块里在这些表操做的基础上去封装该模块的不同业务service(从而形成有多个service的组建,提供该模块的业务api),每个业务都可以拥有同模块的所有的表操作对象作为DB功能对象(DAO对象实现),这样做就可以利用DAO层和业务层减少平级的依赖。
    当然在这种情况下还是会出现依赖,但这个时候的依赖就是组建的依赖问题了,基础组建(例如对多个关于员工的表提取各种不同的员工信息的组建,log组建,email组建,总之是经常会被很多模块用到对于项目很通用的通用模块组建)被级别更高更上层的组建所依赖,并形成新的功能组建,这样一来依赖关系变的清晰。
7 楼 jamesby 2007-03-06  
caoyangx 写道
有些时候,如果两个service间互相调用,很容易出现A调B,B调A的情况,这样如果使用springIOC管理的话,会报一个错误。避免这样的事情发生,就需要写一个baseXXXservcie的抽象service,把公用部分进行继承使用,这样就可以解决,类似你的第一种行为,但是不是A继承B。
是的,关键是我想更深层次的讨论
如对象什么情况应该使用属性依赖
什么情况应该继承.
什么情况应该使用回调.
什么情况一个对象应该作为另一个对象的方法参数来传递.
准备研究下设计模式的各个协作对象之间的关系是通过哪种方式.
6 楼 caoyangx 2007-03-06  
有些时候,如果两个service间互相调用,很容易出现A调B,B调A的情况,这样如果使用springIOC管理的话,会报一个错误。避免这样的事情发生,就需要写一个baseXXXservcie的抽象service,把公用部分进行继承使用,这样就可以解决,类似你的第一种行为,但是不是A继承B。
5 楼 jamesby 2007-02-24  
andyandyandy 写道
为什么在service层内还要互相调用呢?
似乎把需要多个类调用的东西抽象出去更好吧!
是啊,是因为我设计的不合理,其实根本就没有设计,才引发上面的思考!
4 楼 andyandyandy 2007-02-24  
为什么在service层内还要互相调用呢?
似乎把需要多个类调用的东西抽象出去更好吧!
3 楼 jamesby 2007-02-24  
忽略了一个问题,那就是依赖关系是有方向的,下面的代码均假设Class A 调用 Class B,即依赖关系的方向是A-->B。

依赖关系的继承实现方式

方式一

public class A extends B{
   public void methoda(){
      /**
      *代码段1
      */
      methodb();
      /**
      *代码段2
      */     
   }
}

public class B{
	public void methodb(){
	    /**
	    *methodb的代码
	    */	
	}
}


方式二

public class A extends B{
   public void methoda1(){
      /**
      *代码段1
      */
   }
   public void methoda2(){
      /**
      *代码段2
      */     
   }
}

public class B{
	public void methodb(){
	    methoda1();
	    /**
	    *methodb的代码
	    */
	    methoda2();
	}
	
	public void methoda1(){}
	public void methoda2(){}
}


这个实际上不就是template设计模式嘛!

依赖关系基于属性的实现方式

方式一

public class A{
   private B b;
   public void methoda(){
      /**
      *代码段1
      */
      b.methodb();
      /**
      *代码段2
      */     
   }
}

public class B{
	public void methodb(){
	    /**
	    *methodb的代码
	    */	
	}
}


好象没有方式二

依赖关系基于方法参数的实现方式

方式一

public class A{
   public void methoda(B b){
      /**
      *代码段1
      */
      b.methodb();
      /**
      *代码段2
      */     
   }
}

public class B{
	public void methodb(){
	    /**
	    *methodb的代码
	    */	
	}
}


方式二

public class A{
   public void methoda1(){
      /**
      *代码段1
      */
   }
   public void methoda2(){
      /**
      *代码段2
      */     
   }
}

public class B{
	public void methodb(A a){
	    a.methoda1();
	    /**
	    *methodb的代码
	    */
	    a.methoda2();
	}
}


这个好象是传说中的回调.

通过以上代码又引出一个新的问题,在设计Service的时候除了考虑功能,依赖关系外,还要考虑依赖关系的调用方式是主动调用方式还是被动调用方式?

例如上面代码的方式二均采用被动调用方式,即依赖方向是A-->B,但是调用方向确是从B-->A.
2 楼 jamesby 2007-02-24  
为什么我回复了以后帖子排在前面,但是对回复修改后就排到后面去了?
1 楼 jamesby 2007-02-24  
大家平时都怎么用,我一般采用第二种方案,第三种几乎不用,
大家也可以延伸到接口的继承、属性依赖和方法依赖的设计,
希望大家多提写自己的想法.

相关推荐

    Android实验五.doc

    与Activity不同,它 是不能与用户交互的,不能自己启动的,需要调用Context.startService()来启动,运 行后台,如果我们退出应用时,Service进程并没有结束,它仍然在后台行。Service有 两种启动方式,对应的,有两...

    百度地图毕业设计源码-think-about-backend-develop:对项目组后端开发的思考

    必须由controller调用service,service调用repository,service和repository可调用framework内容。 从设计模式来看,属于SOA,以service为核心,虽然实际开发中大量的业务逻辑泄露到controller和repository中(甚至...

    dubbo-kubernetes:Apache Dubbo与k8s集成

    初步思考 kubernetes是天然可作为微服务的地址注册中心,类似于zookeeper、Consul。 具体来说,kubernetes中的Pod是对于应用的运行实例,Pod的被调度部署/启停都会调用API-Server的服务来保持其状态到ETCD;...

    Java高级玩法-SPI的基本使用

    SPI的全称是Service Provider Interface,是Java提供的可用于第三方实现和扩展的机制,通过该机制,我们可以实现解耦,SPI接口方负责定义和提供默认实现,SPI调用方可以按需扩展 API的全称是Application ...

    亮剑.NET深入体验与实战精要2

    7.6.2 通过Microsoft.XMLDOM调用Web Service 291 7.6.3 XMLHTTP POST调用Web Service 293 7.6.4 SOAP调用Web Service 293 7.7 WinForm如何调用Web Service 295 7.7.1 .NET的WinForm调用Web Service 295 7.7.2 手动...

    亮剑.NET深入体验与实战精要3

    7.6.2 通过Microsoft.XMLDOM调用Web Service 291 7.6.3 XMLHTTP POST调用Web Service 293 7.6.4 SOAP调用Web Service 293 7.7 WinForm如何调用Web Service 295 7.7.1 .NET的WinForm调用Web Service 295 7.7.2 手动...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    8.3.2 开发本地调用的无状态 Session Bean 311 8.4 发布Session Bean 314 8.4.1 打包EJB-JAR 315 8.4.2 Annotation与部署描述文件 315 8.5 开发有状态的Session Bean 318 8.6 Session Bean的生命周期 321 8.6.1 无...

    深入理解Android:卷I--详细书签版

    本章拓展思考部分讨论了与Binder有关的三个问题,它们分别是Binder和线程的关系、死亡通知以及匿名Service。笔者 希望,通过本章的学习,大家能更深入地认识Binder的本质。  第7章阐述了Audio系统中的三位重要...

    InitPHP轻量级开源框架 版本3.8

    ...  InitPHP采用了分层体系架构,在MVC模式基础上进行延伸!  详细的API文档和使用Zend studio开发代码提示,让您开发更加速度!  我们对每一个框架函数进行了思考... 新增框架Service的RPC的调用功能,使业务分割

    混淆java隐藏源码-ExportImageSOI:ArcGISServer对象拦截器和MemSQL

    思考 。 拦截器的一个用例是基于基于单点登录的请求中的用户凭据来操纵层或数据字段的可见性。 与已发布的 MXD 相关联的 SOI 的另一个用例是拦截导出图像操作并对原始结果图像进行数字水印以用于版权目的。 每当在 ...

    asp.net知识库

    DbHelperV2 - Teddy的通用数据库访问组件设计和思考 也论该不该在项目中使用存储过程代替SQL语句 如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典...

    Spring.net框架

    在这个系列中一共包含6个案例,从简单到复杂,也是对问题分解、思考和解决的一个过程,它们分别是: (1)类之间的依赖; 降低 (2)接口依赖; (3)基 于配置文件和Reflection的工厂模式; (4)使用Spring.net...

    《iOS6开发指南》精彩书摘

    最后介绍了程序外地图的使用,如何调用iOS 6苹果地图和调用谷歌Web地图。  第三部分进阶篇,介绍iOS高级内容,商业思考等,包括内容如下: 第14章“iOS中的商业模式”。了解iOS中的商业模式,其中的收费策略值得...

    ObjectARX 人机交互技术原型程序介绍

    使用环境: Visual C++ 6.0 ,请不要安装各种各样的 Service Pack,展开目录 MRXEXT 中,就相当于我们设计的 ObjectARX 代码,使用命令 Appload 调入这个 MFC 扩展动态连接库(MRXEXTD.MRX),可以使用的命令有:...

    Google Android SDK开发范例大全(第3版) 1/5

    Web Service存取服务:内嵌网页浏览器、Ajax网页特效、手机气象局、网络播放mp3、网络安装apk程序、远程下载手机铃声、XML-RPC移动博客发布器、手机RSS阅读器、地震速报、网页快照等。 完备的Google网络服务:Google...

    Google Android SDK开发范例大全(第3版) 4/5

    Web Service存取服务:内嵌网页浏览器、Ajax网页特效、手机气象局、网络播放mp3、网络安装apk程序、远程下载手机铃声、XML-RPC移动博客发布器、手机RSS阅读器、地震速报、网页快照等。 完备的Google网络服务:Google...

    Google Android SDK开发范例大全(第3版) 3/5

    Web Service存取服务:内嵌网页浏览器、Ajax网页特效、手机气象局、网络播放mp3、网络安装apk程序、远程下载手机铃声、XML-RPC移动博客发布器、手机RSS阅读器、地震速报、网页快照等。 完备的Google网络服务:Google...

Global site tag (gtag.js) - Google Analytics