把3000行程式碼重構成15行,這樣做!
把三千行程式碼重構為 15 行
-
要在程式設計過程中多思考 -
程式設計的思想很重要,請多看點經典的書 -
從小處著眼,慢慢重構,尤其在應對一個大型的系統 -
當重複出現的時候,你應該考慮重構了 -
貼上複製的程式碼越少,你的系統越穩定
少用程式碼生成器
-
因為使用了動軟程式碼生成器,生成程式碼方便,就沒多想了。 -
三層架構的概念倒是瞭解了,但是沒有去深入思考就拿來應用 -
遇到重複的程式碼,沒有重構的概念,這是思想的問題 —— 思想比你的能力重要
for ( int n = 0; n < rowsCount; n++)
{
model = new DBAccess.Model.eventweek();
if(dt.Rows[n][ "GroupNo"].ToString()!= "")
{
model.GroupNo= int.Parse(dt.Rows[n][ "GroupNo"].ToString());
}
if(dt.Rows[n][ "Week0"].ToString()!= "")
{
model.Week0= int.Parse(dt.Rows[n][ "Week0"].ToString());
}
if(dt.Rows[n][ "Week1"].ToString()!= "")
{
model.Week1= int.Parse(dt.Rows[n][ "Week1"].ToString());
}
}
不要重複發明輪子
public List< string> GetDevices( string dev){
List< string> devs= new List< string>();
int start= 0;
for( int i= 0;i<dev.Length;i++){
if(dev[i]== '^'){
devs.Add(dev.SubString(start,i));
start=i+ 1;
}
}
return devs;
}
-
重複發明輪子。花費了額外的時間,函式的健壯性和很差 -
可讀性差。其實是一個很簡單的功能,但是用上了這麼一段函式,起初我還以為有什麼特別的功能。
-
瞭解你所學的程式語言的特性。你可以看一本基礎的入門書籍,把所有的特性瀏覽一遍,或者上 MSDN,把相關的內容過一遍。 -
在你決定動手發明一個輪子之前,先搜尋一下現成的解決方案。你還可以到 CodeProject、GitHub 之類的網站搜尋一下。在知乎上有很多人都在批評這麼一種現象,老是問一些重複性的問題,然後又職責知乎沒落了,沒有人回答他的問題,實際上相關問題已經有了很詳細的解答,那提問之前,不能首先去搜一下是否有現成的答案,反而指責沒有回答他的問題呢? -
你有一定的基礎之後,還應該去讀一下相關的經典書籍,深入瞭解其中的原理。比如,你覺得你有一定的基礎了,我建議你去把《CLR Via C#》多讀幾遍,你瞭解原理越多,你越是能夠利用這程式語言的特性,從而來實現原本那些你認為要靠自己寫程式碼的功能。
public abstract class MissionBase : IMission
{
private DateTime _nextExecuteTime;
protected virtual DateTime[] ExecuteTimePoints { get; private set; }
protected virtual int IntervalSeconds { get; private set; }
protected IEngine Engine { get; private set; }
public bool IsCanceled{ get{……}}
public bool IsExecuting{ get{……}}
public bool IsTimeToExecute{ get{……}}
public abstract bool Enable { get; }
public abstract string Name { get; }
protected MissionBase( IEngine engine)
{
ExecuteTimePoints = null; //預設採用間隔的方式
IntervalSeconds = 60 * 60; //預設的間隔為1個小時
Engine = engine;
}
/// 任務的執行方法
public void Done()
{
if (Interlocked.CompareExchange( ref _isExecuting, 1, 0) == 1) return;
try
{
……
}
finally
{
Interlocked.CompareExchange( ref _isExecuting, 0, 1);
}
}
///實際方法的執行
protected abstract void DoneReal();
}
等你無法重構的時候再考慮重寫
-
需要花更大的精力來完成一些看似簡單的 BUG
你要知道,有一部分看似錯誤或者非常不優美的程式碼,其實恰恰是為了解決一些非常刁鑽的問題的。 -
再也無法相容老的系統了
你急於把原有系統重寫,卻往往忽略了對原有系統的相容,那麼你新的系統的推進則會十分緩慢。 而老系統的維護,又會陷入及其尷尬的情況。 -
過度設計,導致重寫計劃遲遲無法完成
有重寫衝動的程式設計師往往是在架構設計上有一些讀到的見解,他們善於利用所學的各種設計模式和架構技巧來建立系統,但是越是想盡可能的利用設計模式,越是陷入過度設計的困局,導致重寫的計劃遲遲都無法完成。 -
無法有效利用現有系統已經完成並測試的程式碼
如果你確實有必要進行重寫,我還是建議你把程式碼儘可能的重構。 因為重構之後的系統,能夠讓你更輕易的重寫,又最大限度了保留以前可用的 業務程式碼。
class MainEngine:IEngine{
public MainEngine (ConfigSettings config){
}
public void Start ();
public void Stop ();
}
class ConfigSettings{
public bool NewFuncEnable{ get; private set;}
public ConfigSettings(){
NewFuncEnable=xx; //從配置檔案讀取
}
}
class MainEngine:IEngine{
private NewFuncClass newCls= new NewFuncClass();
public MainEngine (ConfigSettings config){
}
public void Start (){
if(config.NewFuncEnable)
newCls.Start();
}
public void Stop (){
if(config.NewFuncEnable)
newCls.Stop();
}
}
-
主程式程式碼和擴充套件功能耦合性太強,每增加一個功能都要修改主程式程式碼,這裡非常非常容易出錯。尤其是新的人進度開發組,很容易就忘主程式中增加了一些致命性的程式碼。比如上述的擴充套件功能,可能是在特定的專案中才會有這個擴充套件功能,但是,寫程式碼的人忘記增加是否啟用的配置選項了,導致所有的專案都應用了這個功能,而這個功能需要特定的表,這樣就悲劇了。即使是你增加了配置,也是非常的不美觀,因為在通用的版本中使用了這個配置,往往會讓定製專案以外的人員感到困惑。 -
增加擴充套件功能的人還需對整個 MainEngine 程式碼有一定的熟悉,否則,他根本就不知道在 Start 方法和 Stop 方法進行 newClas 的對應方法的呼叫 -
如果你打算對這段程式碼進行重寫,那麼,你會感到非常的困難,因為你分不清楚 newCls 這個新例項的作用,要麼你花大精力去把所有程式碼理清楚,要麼直接就把這段新增的業務程式碼去掉了。
private void RegisterTaskHandlerBundles()
{
var bundles = xxx.BLL.Caches.ServiceBundleCache.Instance.GetBundles( "TaskHandlerBundle");
if (bundles != null && bundles.Count > 0)
{
var asmCache = new Dictionary< string, Assembly>();
foreach ( var bundle in bundles)
{
try
{
if (!asmCache.ContainsKey(bundle.Category)) asmCache.Add(bundle.Category, Assembly.Load(bundle.AssemblyName));
var handler = (ITaskHandler)asmCache[bundle.Category].CreateInstance(bundle.ClassName, false, BindingFlags.Default, null,
new object[] { this, bundle }, null, null);
_taskHandlerBundles.Add(bundle, handler);
}
catch (Exception e)
{
NLogHelper.Instance.Error( "載入bundle[Name:{0},Assembly:{1}:Class:{2}]異常:{3}", bundle.Name, bundle.AssemblyName, bundle.ClassName, e.Message);
}
}
}
}
class MainEngine:IEngine{
private NewFuncClass newCls= new NewFuncClass();
public MainEngine (ConfigSettings config){
RegisterTaskHandlerBundles();
}
public void Start (){
_taskHandlerBundles.Start();
}
public void Stop (){
_taskHandlerBundles.Stop();
}
}
-
新增的類只需按規範寫即可,完全對 MainEngine 程式碼沒有任何影響。你甚至可以把這個 MainEngine 程式碼寫在一個新建的 Dll 中。 -
新增功能的這個業務類跟原來的程式碼解耦,非常方便進行新功能的業務測試,而無需考慮原有框架的影響 -
新增功能的業務類與架構完全分離,我們在重寫程式碼中只要保證介面的穩定性,無論我們怎麼把系統架構重寫,我們可以馬上就重用上原有的業務功能程式碼。
學會單元測試,培養你的重構意識
所謂重構
-
把基礎打牢固 -
多看點優秀的程式碼 -
避免複製貼上,如果看見重複程式碼時應該有意識要消滅它 -
減少對程式碼生成器的依賴 -
在處理現有程式碼時儘量用重構代替重寫,在重寫之前一定要先重構 -
儘量讓所有的方法都是可測試的
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31556440/viewspace-2674448/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從把3000行程式碼重構成15行程式碼談起行程
- 從把三千行程式碼重構成15行程式碼談起行程
- 3000行程式碼怎樣簡化成300行?來,一文來教你!行程
- 程式碼重構與單元測試——對方法的引數進行重構(五)
- 執行效率高的程式碼-可以這樣寫出來~
- 實際業務中使用策略模式對程式碼進行重構模式
- 程式碼重構--大話重構
- 15行CSS程式碼 就可以讓你的手機軟重啟CSS
- 程式碼重構
- 如果兩個程式都這樣做會怎樣?
- 程式碼重構之法——方法重構分析
- 這樣執行執行緒是否妥當?執行緒
- “硬核”程式碼重構
- 重構 PHP 程式碼PHP
- PHP程式碼重構PHP
- 程式碼重構(四)
- 怎樣用一行 Python 程式碼實現並行Python並行
- 你的程式語言能這樣做嗎?
- 月薪從3000到8000 程式設計師為高薪轉行做吊頂工程式設計師高薪
- 200 行 Python 程式碼做個換臉程式(附原始碼)Python原始碼
- 編寫可測試的Javascript程式碼(2):從反模式進行重構JavaScript模式
- 程式碼重構技巧(二)
- 談談程式碼重構
- 【讀程式碼重構有感】
- 重構:程式碼異味
- 百萬年薪挖大學教授做程式設計師,學生變成上司,這樣好嗎?程式設計師
- 這樣的專案還有價值重構嗎?
- 開發好能重構的程式碼,都是這麼幹的
- 程式碼重構:類重構的 8 個小技巧
- .NET重構—單元測試的程式碼重構
- 怎樣做才能保證執行緒安全?執行緒
- 程式設計師這樣寫程式碼程式設計師
- 為什麼我要豎向對齊程式程式碼(你也應該這樣做)
- 100行Java程式碼構建一個執行緒池Java執行緒
- 碼農自白:這樣成為谷歌工程師谷歌工程師
- 把 java project 釋出成為可執行檔案JavaProject
- 一行程式碼解決求重問題行程
- 程式碼重構那些事兒