一、前面的話
在動筆之前,一直很糾結到底要不要繼續完成這個工具,因為上次給它碼代碼還是一年多之前的事情,參考自己動手寫工具----XSmartNote [Beta 2.0],這篇博文里,很多園友提出了寶貴的意見。最后決定吸收園友的建議把這個工具重構一下。首先給它換了個名 稱,XSmartNote。因為各種自身的原因,並沒有完成這個工具的基本功能,只是實現了基本的框架。最近有點時間就搞了一下,權當做打下基礎。本來想用B/S結構來重新搞一下,畢竟園子里有很多大牛都是專注於ASP.NET MVC,但仔細想想還是不要總寫一些爛尾樓工程的好,其實采用那種架構都無所謂,畢竟是個人使用的小工具,一個是事件驅動、一個是請求響應模型,不同的也是只表現方式不一樣。
二、XSmartNote能干什么?
每天都在關注着園子里的動態,看着各位大神分享着各種新技術,感覺自己要學習的東西太多了,但是各種知識點零零散散地沒有分門別類,看過后又忘記了,很難達到學習的效果。所以希望能通過對知識的標簽化,進行分門別類的總結梳理,想看的時候,通過標簽來查找過濾出相關的知識點,進行學習和鞏固,豈不美哉~這也同樣適用於對編程經驗的總結,養成習慣后,時間久了,所積累下來的可是一筆不小的知識財富。補充一句,有人會說現在網上有很多很多的現成的工具,如印象筆記、有道雲筆記,各種筆記... ...干嘛不用?我只想說,用自己造的東西會很爽好嘛!
三、和上一個版本有什么區別?
在上一個版本中,只是簡單地勾勒出一個大概的輪廓,目前的版本對上一個版本進行了擴充和實現,與上一個版本還是有很大區別的
1、底層數據操作
數據層由原來基本的最基礎的ADO.NET操作,新版本中摒棄了最基本的SQL操作,采用了NHibernate框架,該框架為我們封裝了很多的功能,這樣就大大減少了工作量,避免了過多的sql腳本的編寫,同時也避免了由腳本數量過大不可避免產生Bug的問題。NHibernate框架提供了對原生sql的支持,多表查詢和復雜查詢,可以直接使用原生sql,還支持Example查詢。NHibernate配備了一種非常強大的查詢語言HQL,這種語言看上去很像SQL。但是不要被語法結構上的相似所迷惑,HQL是有意識地被設計為完全面向對象的查詢語言,它可以理解如繼承、多態和關聯之類的概念。NHibernate框架還有很多高級功能,如事務並發、提高性能的二級緩存等,由於沒有使用,暫且不做討論。
以下代碼實現了根據Post的Id找到所有Tag,借助ADO.NET原生數據操作方式,可以看到,需要自己手動編寫SQL腳本,這僅僅是這個小的功能點,如果涉及的表相對較多,那出錯的幾率就會大大提升,而且錯誤在編譯期是看不出來的,這樣就有可能會把錯誤推向運行期。
1 private static DataTable QueryTable(StringBuilder sbcmd) 2 { 3 using (SqlConnection conn = SQLHelper.CreateConnection()) 4 { 5 conn.Open(); 6 using (SqlCommand cmd = new SqlCommand(sbcmd.ToString(), conn)) 7 { 8 DataTable dt = new DataTable(); 9 SqlDataAdapter sda = new SqlDataAdapter(); 10 sda.SelectCommand = cmd; 11 sda.Fill(dt); 12 return dt; 13 } 14 } 15 }
1 //取得指定文章Id包含的標簽 2 public static DataTable GetTagsByPostId(int id) 3 { 4 StringBuilder cmd = new StringBuilder( 5 string.Format("select t.tagContent,t.tagId from Table_Content c,Table_Content_Tag ct,Table_Tag t ")); 6 cmd.Append(string.Format(" where c.Id=ct.postId and t.tagId=ct.tagId and c.id={0} ", id)); 7 return QueryTable(cmd); 8 }
下面來看看采用NHibernate框架后,這段代碼的實現。可以明顯地看出,代碼量減少,結構清晰,僅僅需要一行代碼就可以取得指定Post的所有Tag。
1 //取得指定文章Id包含的標簽 2 public IList<Tag> GetTagsByPostId(Guid Id) 3 { 4 IList<Model.Tags.Tag> tags = null; 5 using (ISession session=sessionFactory.OpenSession()) 6 { 7 ITransaction trans = session.BeginTransaction(); 8 try 9 { 10 tags = session.CreateCriteria(typeof(Tag)).CreateCriteria("Posts").Add(Restrictions.Eq("Id", Id)).List<Tag>(); 11 } 12 catch (Exception) 13 { 14 trans.Rollback(); 15 throw; 16 } 17 return tags; 18 } 19 }
2、界面優化
先看下整體效果:
多主題支持:
在上一個版本中,由於只顧架構功能的設計,沒有把重心放在界面的美化上。該版本采用了免費的CSkin界面庫,對於提升界面UI整體的效果還是不錯的,只需引用相關DLL組件即可。CSkin界面庫是免費使用的,但是源碼並不開源。以下是官方對CSkin界面庫的簡要的描述。
精簡大量不必要代碼,減小UI庫體積,優化程序速度,使得庫更加輕巧好用。
啟用全新CSkin界面引擎,重塑界面UI每個角落,帶來嶄新體驗,更加流暢輕快簡潔,更不簡單。
大量減少生硬的變換效果,注入更多輕快靈動的變化反饋,響應迅速。
同時支持多主題切換,目前有玫瑰紅、寶石藍、青蔥綠、小鴨黃等主題(主題名稱是我自己想的,有更好的意見可以告訴我),后續會支持更多主題配色方案,並且開放接口,允許以插件的方式開發自己喜歡的主題樣式。同時增加了主界面對各個分辨率屏幕尺寸的自適應。讓工具不僅僅是工具,用起來更舒心,提高使用的積極性。
3、提升性能
重構代碼的時候,發現有好多代碼段大量地創建新對象,如果我們使用過程中,積累的Note和標簽越來越多,是會影響到工具性能的,所以把一些常用的設計模式融入到軟件之中。例如,每個實體都有一個自己的數據庫操作類,這里我把數據庫操作類封裝成單例模式,這樣每次使用的都是同一個對象,如果不存在該對象或該對象被銷毀才會創建新的對象,這樣就提升了工具的性能。例如,下面的主題管理類:
1 //主題管理類 2 public class ThemeManager:IThemeManager 3 { 4 private static ThemeManager themeManager; 5 private MainForm mainForm; 6 private event Action<ThemeEnums.ThemeEnum> ThemeChangeEvent; 7 private static object _lock = new object(); 8 private ThemeManager(MainForm mainForm) 9 { 10 this.mainForm = mainForm; 11 ThemeChangeEvent += mainForm.SetTheme; 12 } 13 14 public static ThemeManager CreateThemeManager(MainForm form) 15 { 16 ThemeManager _themeManager; 17 if (themeManager == null) 18 { 19 lock (_lock) 20 { 21 if (themeManager == null) 22 { 23 _themeManager = new ThemeManager(form); 24 themeManager = _themeManager; 25 } 26 } 27 } 28 return themeManager; 29 } 30 31 public void ChangeFormTheme(ThemeEnums.ThemeEnum enums) 32 { 33 if (ThemeChangeEvent != null) 34 { 35 ThemeChangeEvent(enums); 36 } 37 } 38 }
以及每個實體的數據操作類,這里以PostContents為例:
1 //PostContents操作類 2 public class PostContentsDAO : IPostContentsDAO 3 { 4 private ISessionFactory sessionFactory; 5 private static PostContentsDAO PostContentsDao; 6 private static object _lock = new object(); 7 private PostContentsDAO() 8 { 9 //在構造函數中獲取配置,並產生SessionFactory 10 var cfg = new NHibernate.Cfg.Configuration().Configure("../../Config/hibernate.cfg.xml"); 11 sessionFactory = cfg.BuildSessionFactory(); 12 } 13 14 public static PostContentsDAO CreatePostContentsDAO() 15 { 16 PostContentsDAO _PostContentsDao; 17 if (null == PostContentsDao) 18 { 19 lock (_lock) 20 { 21 if (null == PostContentsDao) 22 { 23 _PostContentsDao = new PostContentsDAO(); 24 PostContentsDao = _PostContentsDao; 25 } 26 } 27 } 28 return PostContentsDao; 29 } 30 }
4、自定義控件
更新了若干個用戶自定義控件,包括帶CheckBox的可選標簽、普通的Note展示標簽以及僅用於展示標簽的圓角矩形控件,采用自定義控件可以最大程度上靈活地控制控件的屬性以及事件,無論從靈活性和外觀上都是不錯的選擇。后面的文章我會單獨把控件拿出來分享。
四、以后會有什么炫酷功能?
關於這個問題,我很認真地思考了一下,大概總結了如下幾個功能點:
1、 目前的版本還尚未實現根據標簽篩選Note的功能,只是將標簽與Note相關聯,后續版本會根據標簽進行實時過濾;
2、 對代碼片段的支持,我會編寫一個用戶控件專門用於對代碼編輯的支持,它和文本編輯的方式是不同的,我覺得這是最炫酷的功能啦;
3、 增加控制面板,把一些功能的接口暴露出來,以控制面板的方式展現在用戶面前,隨心所欲地進行配置,如主界面透明度、顏色、控件屬性等,更加豐富靈活;
4、 集成自定義翻頁控件,目前的版本右側Note展示區域默認顯示某類別下的所有Note,並且存在萬惡的滾動條,用起來不是很方便,所以我會集成一個漂亮的翻頁控件,目前正在開發中;
5、 支持插件式開發,工具會提供一些接口,以插件的方式開發用戶自己的特有功能,比如以插件的方式開發自己喜歡的主題或是一些定制功能;
6、 添加系統日志,記錄用戶的每一個操作,以及系統錯誤信息收集。
7、 多數據庫支持。目前我采用的數據庫是SQL Server 2008 R2版本,有點大材小用了,后續會支持Access、SQLite,這樣就會便於攜帶,放在U盤里也可以喲~
五、嘮叨一下
目前這個小工具在功能層面還處在初級階段,上面第四點中提及的功能好多都還沒有實現,本文中只截取了一點點代碼用於解釋版本差異,全部代碼我會發布到GitHub上。由於本人時間和精力有限,所以希望園子里有興趣的園友能和我一起完善這個工具。在這里附上GitHub地址,XSmartNode 。求Star,求Star,求Star。后面的文章中我會把相關的控件開發過程貼出來,都是一些基礎性的東西,希望對初學者有所幫助,大神請繞道。本人能力有限,如果在表述的過程中有什么錯誤,還請多多指教,感激不盡。另外,我會把本篇文章同步發布到我的簡書上。如果覺得文章還可以,請推薦一下哦,您的推薦是我寫工具的最大動力!
作者:悠揚的牧笛
博客地址:http://www.cnblogs.com/xhb-bky-blog/p/5504570.html
聲明:本博客原創文字只代表本人工作中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關系。非商業,未授權貼子請以現狀保留,轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文連接。