论坛首页 Java企业应用论坛

关于Service调用Service 的思考

浏览 5881 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-02-10  
OO
以前做软件都是随便写几个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已经很熟悉了,相信前两种大家用的很多,第三种在开源框架用的比较多.
   发表时间:2007-02-24  
大家平时都怎么用,我一般采用第二种方案,第三种几乎不用,
大家也可以延伸到接口的继承、属性依赖和方法依赖的设计,
希望大家多提写自己的想法.
0 请登录后投票
   发表时间:2007-02-24  
为什么我回复了以后帖子排在前面,但是对回复修改后就排到后面去了?
0 请登录后投票
   发表时间: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.
0 请登录后投票
   发表时间:2007-02-24  
为什么在service层内还要互相调用呢?
似乎把需要多个类调用的东西抽象出去更好吧!
0 请登录后投票
   发表时间:2007-02-24  
andyandyandy 写道
为什么在service层内还要互相调用呢?
似乎把需要多个类调用的东西抽象出去更好吧!
是啊,是因为我设计的不合理,其实根本就没有设计,才引发上面的思考!
0 请登录后投票
   发表时间:2007-03-06  
有些时候,如果两个service间互相调用,很容易出现A调B,B调A的情况,这样如果使用springIOC管理的话,会报一个错误。避免这样的事情发生,就需要写一个baseXXXservcie的抽象service,把公用部分进行继承使用,这样就可以解决,类似你的第一种行为,但是不是A继承B。
0 请登录后投票
   发表时间:2007-03-06  
caoyangx 写道
有些时候,如果两个service间互相调用,很容易出现A调B,B调A的情况,这样如果使用springIOC管理的话,会报一个错误。避免这样的事情发生,就需要写一个baseXXXservcie的抽象service,把公用部分进行继承使用,这样就可以解决,类似你的第一种行为,但是不是A继承B。
是的,关键是我想更深层次的讨论
如对象什么情况应该使用属性依赖
什么情况应该继承.
什么情况应该使用回调.
什么情况一个对象应该作为另一个对象的方法参数来传递.
准备研究下设计模式的各个协作对象之间的关系是通过哪种方式.
0 请登录后投票
   发表时间:2007-03-06  
   (个人意见和经验)继承最好不要用,因为偶合性太强,一般依赖关系存在的话的也只能是单向依赖,
尽量将平级的组建在设计的时候就简单设计成为依赖关系的,一但平级的关系变少,组建相互依赖的可能就被最大的降低了(相互依赖形成构造的死循环)。
    同时也最好是定模块的时候把关系比较近的表操作定义在一个模块里面,再在这个模块里在这些表操做的基础上去封装该模块的不同业务service(从而形成有多个service的组建,提供该模块的业务api),每个业务都可以拥有同模块的所有的表操作对象作为DB功能对象(DAO对象实现),这样做就可以利用DAO层和业务层减少平级的依赖。
    当然在这种情况下还是会出现依赖,但这个时候的依赖就是组建的依赖问题了,基础组建(例如对多个关于员工的表提取各种不同的员工信息的组建,log组建,email组建,总之是经常会被很多模块用到对于项目很通用的通用模块组建)被级别更高更上层的组建所依赖,并形成新的功能组建,这样一来依赖关系变的清晰。
0 请登录后投票
   发表时间:2007-03-06  
moshalanye 写道
   (个人意见和经验)继承最好不要用,因为偶合性太强,一般依赖关系存在的话的也只能是单向依赖,
尽量将平级的组建在设计的时候就简单设计成为依赖关系的,一但平级的关系变少,组建相互依赖的可能就被最大的降低了(相互依赖形成构造的死循环)。
    同时也最好是定模块的时候把关系比较近的表操作定义在一个模块里面,再在这个模块里在这些表操做的基础上去封装该模块的不同业务service(从而形成有多个service的组建,提供该模块的业务api),每个业务都可以拥有同模块的所有的表操作对象作为DB功能对象(DAO对象实现),这样做就可以利用DAO层和业务层减少平级的依赖。
    当然在这种情况下还是会出现依赖,但这个时候的依赖就是组建的依赖问题了,基础组建(例如对多个关于员工的表提取各种不同的员工信息的组建,log组建,email组建,总之是经常会被很多模块用到对于项目很通用的通用模块组建)被级别更高更上层的组建所依赖,并形成新的功能组建,这样一来依赖关系变的清晰。
恩,在一般的设计中几乎也就用到这些,依赖取决于该组建的通用性,象楼上说的邮件,log等可能是比较通用的,还有例如目前我的系统中有寻呼系统,短信系统,这些可能都是被依赖的Service,如果在一个系统中有这些功能,可以简单的设计他们的依赖关系,如果是多个系统都有类似功能,怎么办?

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

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

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


0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics