系统中循环引用
系统中存在循环引用的坏处
public class A{
private B b;
public void methodA(){
//dosomthing
b.methodA();
//dosomthing
}
public void methodB(){
}
}
public class B{
private A a;
public void methodA(){
}
public void methodB(){
//dosomthing
a.methodB();
//dosomthing
}
}
从直观上来看,类A
中耦合了类B
,从程序的角度上看,假如类A
的methodB()
方法做了修改,就会导致类B
的methodB
做出相应的修改, 并且还会导致一系列调用B.methodB()
的方法也改变;另一方便如果类B
的methodA()
做出修改也会导致类A
产生相同的副作用.
是否可以避免循环引用的出现
(Service
层本身根据不同的业务职责是可以分成多个层,只要确保在同一层里面的Service
不会互相引用(也不应该引用),复杂的业务需求应当由更上层的Service
提供) 这个思路主要是,同层是不能依赖的,因为存在依赖肯定就会导致相互依赖。如果两个类存在相互依赖,可以产生一个第三者同事依赖这两个类来解决两个类的相互的依赖关系,但是这是一种很理想的情况,实际上如果做到这样,容易整个系统的抽象层次就会变得无比的多,会加大系统的复杂度
public Class DaoA{
pubic void queryStudent();
}
public Class ServiceA{
pubic void queryStudent(){
//dosomething
//DaoA.queryStudent();
//dosomething
}
}
public Class DaoB{
pubic void insetStudent();
public void updateStudent();
}
public Class ServiceB{
pubic void insetStudent(){
ServiceA.queryStudent();
DaoB.insetStudent();
}
pubic void updateStudent(){
//dosomething
DaoB.updateStudent();
//dosomething
}
}
ServiceA
是对学生查询业务的一个抽象,ServiceB
是对学生新增业务的一个抽象。并且由于业务要求,在新增学生的时候必须要先查询学生是否存在,因为ServiceA.queryStudent()
里面已经封装了查询业务,所以直接调用该方法就行了.但是因为同层之间不能相互引用,所以必须出现第一个第三者,同时修改ServiceB
的方法
public Class ServiceB{
pubic void insetStudent(){
DaoB.insetStudent();
}
}
public Class ServiceC(){
pubic void insetStudent(){
ServiceA.queryStudent();
ServiceB.insetStudent();
}
}
所以在service
上面又加了一层,必然系统的复杂度就上来了所以我的想法是:同层次是允许相互依赖的
哪一层才允许相互依赖
如果出现相互依赖的层次越底层,那么由1引起的副作用对系统的影响就越大。从大的SOA
架构上来看的话底层的原子服务是不能相互依赖的,到了上层的组合服务层,是允许相互依赖的;对于某一个原子服务,Dao
层是不允许相互依赖的,但是service
是允许相互依赖的
后记
ServiceA.queryStudent()
这一层封装的由来ServiceB
当然可以不必依赖ServiceA
,只需要把ServiceA.queryStudent()
里面的方法直接copy一份,直接依赖DaoA
.但是如果系统其它地方也需要用到这个queryStudent逻辑,那么它也只能再copy一份,所以为了提高代码的复用性在ServiceA
中抽象一个queryStudent
方法(当然不必等到很多场景下需要这一个query
逻辑才抽象queryStudent
方法,ServiceA
本身可以根据自身的业务提前抽象)合理的抽象层次
和1一样,当发现很多场景需要同时调用ServiceB.insetStudent
和ServiceB.updateStudent
方法完成自己的业务,因为在很多时候ServiceB
就是一个RPC服务了,所以为了性能考虑,就需要把insetStudent
和updateStudent
方法统一成一个方法,刚开始这一层模块内部的组合服务层是很薄的,没有必要独立出去,随着业务场景的增加组合借接口就会慢慢增多,这个时候就可以把这些模块内部的组合服务单独抽象,它的抽象层次是比原来的service
是要高一层,并且可以单独部署和发布