系統中循環引用

系統中循環引用

系統中存在循環引用的壞處

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的方法code

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自己能夠根據自身的業務提早抽象)class

  2. 合理的抽象層次
    和1同樣,當發現不少場景須要同時調用ServiceB.insetStudentServiceB.updateStudent方法完成本身的業務,由於在不少時候ServiceB就是一個RPC服務了,因此爲了性能考慮,就須要把insetStudentupdateStudent方法統一成一個方法,剛開始這一層模塊內部的組合服務層是很薄的,沒有必要獨立出去,隨着業務場景的增長組合借接口就會慢慢增多,這個時候就能夠把這些模塊內部的組合服務單獨抽象,它的抽象層次是比原來的service是要高一層,而且能夠單獨部署和發佈date

相關文章
相關標籤/搜索