资讯专栏INFORMATION COLUMN

系统中循环引用

Rainie / 1058人阅读

摘要:系统中循环引用系统中存在循环引用的坏处从直观上来看类中耦合了类从程序的角度上看假如类的方法做了修改就会导致类的做出相应的修改并且还会导致一系列调用的方法也改变另一方便如果类的做出修改也会导致类产生相同的副作用是否可以避免循环引用的出现层本身

系统中循环引用 系统中存在循环引用的坏处
    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是允许相互依赖的

后记

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66000.html

相关文章

  • Java 流程控制与数组

    摘要:静态初始化简化的语法格式动态初始化动态初始化只指定数组的长度,由系统为每个数组元素指定初始值。也就是说,数组引用变量是访问堆内存中数组元素的根本方式。 顺序结构 程序从上到下逐行地执行,中间没有任何判断和跳转。 分支结构 if条件语句 if语句使用布尔表达式或布尔值作为分支条件来进行分支控制。 第一种形式: if(logic expression) { ...

    DrizzleX 评论0 收藏0
  • JavaScript的垃圾回收和内存泄漏

    摘要:所谓的内存泄漏简单来说是不再用到的内存,没有及时释放。如果一个值不再需要了,引用数却不为,垃圾回收机制无法释放这块内存,从而导致内存泄漏。 前言 程序的运行需要内存。只要程序提出要求,操作系统或者运行时就必须供给内存。所谓的内存泄漏简单来说是不再用到的内存,没有及时释放。为了更好避免内存泄漏,我们先介绍Javascript垃圾回收机制。 在C与C++等语言中,开发人员可以直接控制内存的...

    microelec 评论0 收藏0
  • JavaScript的垃圾回收和内存泄漏

    摘要:所谓的内存泄漏简单来说是不再用到的内存,没有及时释放。如果一个值不再需要了,引用数却不为,垃圾回收机制无法释放这块内存,从而导致内存泄漏。 前言 程序的运行需要内存。只要程序提出要求,操作系统或者运行时就必须供给内存。所谓的内存泄漏简单来说是不再用到的内存,没有及时释放。为了更好避免内存泄漏,我们先介绍Javascript垃圾回收机制。 在C与C++等语言中,开发人员可以直接控制内存的...

    hover_lew 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<