C#動態表達式計算
應該有不少人開發過程中遇到過這樣的需求,我們直接看圖說話:
如上圖所示,其中Entity為實體類,其中包括五個屬性,該五個屬性的值分別來自於數據庫查詢結果;
用戶通過可視化界面進行某些條件的配置以及某些算法的配置並自動生成表達式或者生成數學模型;
程序中需要通過生成的表達式以及動態從數據庫中獲取的數據進行算法映射以及自動計算出結果。
該需求這邊可以舉出幾個應用場景:
1、報表設計器
我們可以通過報表設計器設計數據庫的映射關系並配置數據之間的算法關系,然后動態生成報表;
2、某些采集工具
定向采集指定數據集合並根據某些動態配置的邏輯進行;
3、數據挖掘和分析
面對這樣的需求我們如何實現?
我們需要開發表達式映射引擎和腳本執行引擎?
假如要實現,該如何設計該框架?下一章我將呈現我們的解決方案,這一章就先說這么多,大家也可以暢談以下自己的想法,忙了。。。
代碼的壞味道之三——譯自《重構》
散彈式修改(Shotgun Surgery)
散彈式修改和發散式變化類似,但卻相反。每當你做一種修改你卻必須對很多不同的類做很多小的變化,你面臨的就是散彈式修改。當變化到處都是時,有的變化就不好找到了,這樣很容易漏掉重要的更改。
這種情況下你要使用移動方法(Move Method)和移動字段(Move Field)來把所有的變化放到一個類里。如果沒有現成的類合適,就創建一個類。通常你會用到內聯化類(Inline Class)把一系列行為放到一起。你會有一點發散式變化的問題,但你可以輕松處理它。
發散式變化是一個類經受多種種類的修改,散彈式修改是一處修改改變了很多類。兩種情況你都希望重新組織,這樣理想狀態下一個普通變化和類有一對一的鏈接關系。
依戀情節(Feature Envy)
對象的意義就是他們在技術上是數據和處理數據的操作的打包。常見的問題是一個方法對其他類比對自己所在的類更有興趣。最普遍的嫉妒的焦點就是數據。我們數不清多少次我們看到一個方法為了計算一個值調用了6,7個另一個對象的get方法。幸運的是解決之道是很顯而易見的,這個方法顯然應該歸於別處,所以你用移動方法(Move Method)來達到目的。有時方法中只有一部分有依戀情節,這種情況下用提取方法處理有依戀的部分,用移動方法來給他一個理想的歸宿。
當然不是所有的情況都可以一刀切。通常一個方法使用若干類的特性,那么我們應該把他歸於哪一個類呢?我們用的啟示是取決於哪一個類中有大多數的數據,那么就把方法放在數據一起。如果已經使用提取方法來把方法分解成若干分離的部分,這一步可以做的輕松一些。
當然有一些精妙的模式會打破這一規矩。來自“四人幫”(Gang of Four)策略和訪問者馬上就浮現在腦海。Kent Beck的自委托是另一個例子。你用這些模式模式來處理發散式修改。最基本的規則是把一起修改的東西放在一起。數據和引用數據的行為經常一起修改,但也有例外。當例外出現時,我們把行為移動使變化保持在一個地方。策略和訪問者模式允許你更容易的改變行為,因為他們以進一步的重定向為代價,隔離了一小部分需要倍覆蓋的行為。
數據泥團(Data Clumps)
數據對象像小孩一樣,他們喜歡聚在一群到處游盪。你常常會看到同樣的三,四個數據對象一起出現在很多地方:一些類中的字段,一些方法簽名里的參數。一簇到處都是的數據真的需要被放在他們自己的對象里。第一步是尋找在哪這些數據表現為字段。對這些字段用提取類把一簇轉變為一個對象。然后把你的注意力轉移到方法的簽名上,用引入參數對象后者保全整個對象來縮減他們。馬上帶來的好處是你縮減了很多參數列表簡化了方法的調用。不用為數據團只用了新對象的部分字段擔心。只要你用兩個或更多的字段替換為新的對象,你會進步的。
一個好的測試是考慮刪除一個數據的值:如果你這樣做其它數據是否還有意義?如果沒有,這就是一個明確的信號告訴你要新建一個對象了。
減小字段列表和參數列表很明顯會移除一些壞味道,但一旦當你有了這些對象時,你就擁有制造好味道的機會了。現在你可以尋找依戀情節的例子,那意味着行為可以被加入你的新類里。不久這些類就會成為社群中的高效成員。