系统中循环引用

算法霜晶客
• 阅读 3202

系统中循环引用

系统中存在循环引用的坏处


    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,从程序的角度上看,假如类AmethodB()方法做了修改,就会导致类BmethodB做出相应的修改, 并且还会导致一系列调用B.methodB()的方法也改变;另一方便如果类BmethodA()做出修改也会导致类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是允许相互依赖的

后记

  1. ServiceA.queryStudent()这一层封装的由来
    ServiceB当然可以不必依赖ServiceA,只需要把ServiceA.queryStudent()里面的方法直接copy一份,直接依赖DaoA.但是如果系统其它地方也需要用到这个queryStudent逻辑,那么它也只能再copy一份,所以为了提高代码的复用性在ServiceA中抽象一个queryStudent方法(当然不必等到很多场景下需要这一个query逻辑才抽象queryStudent方法,ServiceA本身可以根据自身的业务提前抽象)

  2. 合理的抽象层次
    和1一样,当发现很多场景需要同时调用ServiceB.insetStudentServiceB.updateStudent方法完成自己的业务,因为在很多时候ServiceB就是一个RPC服务了,所以为了性能考虑,就需要把insetStudentupdateStudent方法统一成一个方法,刚开始这一层模块内部的组合服务层是很薄的,没有必要独立出去,随着业务场景的增加组合借接口就会慢慢增多,这个时候就可以把这些模块内部的组合服务单独抽象,它的抽象层次是比原来的service是要高一层,并且可以单独部署和发布

点赞
收藏
评论区
推荐文章
Stella981 Stella981
3年前
Python对象的循环引用问题
\toc\Python对象循环引用我们来介绍一下Python是采用何种途径解决循环引用问题的。循环引用垃圾回收算法!(https://oscimg.oschina.net/oscnet/3786a746224d888c57cd06086dc52bff3b0.png)上图中,表示的
Stella981 Stella981
3年前
Python中循环引用(import)失败的解决方法
  原文链接:http://blog.ihuxu.com/thesolutiontotheproblemofcircularimportinpython/  我是采用方案三"将引用放到函数内部"解决了这个问题。下面为原文。前言  最近在开发智能家居项目hestiarpi项目中,由于代码结构层级划分不合理,导致了循环
Stella981 Stella981
3年前
Block的循环引用
在ios常见的循环引用中曾经提到过block:!(http://static.oschina.net/uploads/space/2016/0830/112327_c1yY_1463495.png)看看上面最基本的block循环应用,self包含block,block包含了self中的变量val,所以形成了循环应用,编译器给出了循环引用的警告,当
Stella981 Stella981
3年前
Spring core 源码分析
    上节提到了在AbstractApplicationContext调用refresh方法里,初始化所有BeanDefinitions后,遍历所有BeanDefinitionNames后,循环调用BeanFactory的getBean(name)方法,实例化所有容器Bean对象(非lasyinit)。GetBean做了什么?循环引用如何处理
Stella981 Stella981
3年前
NSTimer循环引用的几种解决方案
前言在iOS中,NSTimer的使用是非常频繁的,但是NSTimer在使用中需要注意,避免循环引用的问题。之前经常这样写:(void)setupTimer{self.timerNSTimerscheduledTimerWithTimeInterval:1target:selfselector:@s
Stella981 Stella981
3年前
JVM学习第二天
引用计数算法对象中添加一个引用计数,一个地方引用它时,计数器值就加1,当引用失效时,计数器值就减一两对象互相引用,就会造成死循环,无法回收可达性分析算法通过GCRoots作为起点,向下搜索,到达不了的对象,即证明对象不可用GCRoots包括:虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用
Stella981 Stella981
3年前
JVM笔记整理
不对之处还望指正。垃圾回收1\.如何判断对象是垃圾对象?引用计数法在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值1,当引用失效时,则值1.此方式不能解决循环引用的问题。验证添加gc日志,\_005GC.javaverbose:gc
Stella981 Stella981
3年前
JVM垃圾回收算法
一、如何判断对象时候需要回收1.引用计数法        给对象添加一个引用计数器,每当有一个地方引用它,计数器加1;引用失效时,计数器减1。计数器为0的对象就表示不可用。      优点:效率高,实现简单。      缺点:对象间如果存在循环引用的情况,就会导致计数器不可能为0,计数器无法通知GC进行回收。2.可达性分析算法
Stella981 Stella981
3年前
JVM调优总结(三)
可以从不同的的角度去划分垃圾回收算法:按照基本回收策略分引用计数(ReferenceCounting):比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。标记清除(MarkSweep):
Stella981 Stella981
3年前
JVM垃圾回收机制
引用计数法:当给对象添加一个引用计数器,每当有一个地方引用这个对象时计数器值就1;引用失效时,计数器值就1;任何时刻计数器为0的对象就是不可能在被使用。优点:引用计数收集器可以很快地执行,交织在程序运行中。缺点:无法检测出循环引用。例如:MyObjectobject1newMyObject();MyObjectobject2
小万哥 小万哥
1年前
Python 集合(Sets)2
访问项您无法通过引用索引或键来访问集合中的项。但是,您可以使用for循环遍历集合项,或者使用in关键字检查集合中是否存在指定的值。示例,遍历集合并打印值:Pythonthisset"apple","banana","cherry"forxinthisset