不要問我是.net程序員還是java程序員,我是業務程序員。
工作多年,我覺得業務程序員,不應該造輪子。
多年以前,我就喫過造輪子的虧,有時,我工作大概60%的時間在造輪子、改輪子的BUG,40%的時間在寫業務功能。
爲什麼要造輪子呢,爲了學技術,爲了不認輸。但是造輪子的代價很大,也影響工作,寫着業務代碼呢,突然出現BUG,而且是輪子的BUG,程序跑不下去了,然後去改輪子的BUG,很浪費時間。
業務代碼有BUG很正常,隨手就改了。但輪子最好不要有BUG,因爲容易坑人。
但BUG總是存在的,怎麼才能儘量避免BUG呢?要有完善的單元測試。怎麼才能及時發現BUG呢?要有一定的用戶量。
但是我的單元測試不夠專業不夠完善,也沒有什麼用戶,我總結出來一些適合我自己的經驗,只要不寫代碼,就沒有BUG,只要代碼寫的少,BUG就少,所以,我把髒活扔了,把它降級爲一個Dapper擴展。即便如此,依然付出了很多時間代價,也非常折騰人。
前兩天,發現了一個嚴重BUG,然後修改後重新發布了。本着負責的態度,覺得這個BUG比較嚴重,把自己不再維護的舊庫也修復重新發布了。但新舊多個版本的維護真的很累人。
單元測試、其它測試工程都測試通過了,又靜態檢查了代碼,覺得沒有問題了。可是,使用該輪子的業務代碼居然又報錯了,是輪子的錯誤。然後修改重新發布,把各種流程又走了一遍,好在不再維護的舊庫沒有這個問題,省了一些時間。
這個BUG有點意思,單元測試考慮到了,但沒有測出來,如果是業務代碼,可能完全沒有問題,但輪子要考慮各種情況。
有BUG的代碼如下:
/// <summary>
/// 提交事務
/// </summary>
public void CommitTransaction()
{
if (_tran == null) return; //防止重複提交
try
{
_tran.Commit();
}
catch
{
RollbackTransaction();
throw;
}
finally
{
if (_tran != null)
{
if (_tran.Connection.State != ConnectionState.Closed) _tran.Connection.Close();
_tran.Dispose();
_tran = null;
}
}
}
我的單元測試代碼使用的是MySql.Data庫,沒有問題。但我的項目中使用的庫是MySqlConnector庫,報空指針異常,因爲MySqlConnector庫,成功提交事務後,事務的Connection屬性就被置爲null了。修復後的代碼如下:
/// <summary>
/// 事務關聯的數據庫連接
/// </summary>
private DbConnection _connForTran;
/// <summary>
/// 開始事務
/// </summary>
public DbTransaction BeginTransaction()
{
var conn = GetConnection();
if (conn.State == ConnectionState.Closed) conn.Open();
_tran = conn.BeginTransaction();
_connForTran = _tran.Connection;
return _tran;
}
/// <summary>
/// 提交事務
/// </summary>
public void CommitTransaction()
{
if (_tran == null) return; //防止重複提交
try
{
_tran.Commit();
}
catch
{
RollbackTransaction();
throw;
}
finally
{
if (_tran != null)
{
if (_connForTran != null)
{
if (_connForTran.State != ConnectionState.Closed) _connForTran.Close();
_connForTran = null;
}
_tran.Dispose();
_tran = null;
}
}
}
業務程序員不建議造輪子,但這是很矛盾的事。造輪子確實可以學到寫業務代碼學不到的技術。