山頂洞人日記 -  回歸到最純樸的開發 王建興 qing@cs.nthu.edu.tw (Email/MSN) twitter://qing_wang http://blog.qing.tw 2008/5/16
審視你的需求 <ul><li>慾望總是超過真實需求 </li></ul><ul><li>威力強大的東西難免複雜 </li></ul><ul><li>選擇開發工具要在複雜度與威力之間選擇一個適合你的平衡點 </li></ul>
山頂洞人過的日子 <ul><li>WinCVS </li></ul><ul><li>EditPlus </li></ul><ul><li>Ant </li></ul><ul><li>MySQL </li></ul><ul><li>Tomcat ...
簡易級 Java Web 應用程式開發 <ul><li>不用 IDE </li></ul><ul><ul><li>用 Editplus 來編輯原始碼 </li></ul></ul><ul><ul><li>用 WinCVS 來做 project ...
關於 Ant <ul><li>為各種類型的專案建立不同 build.xml 的 template </li></ul><ul><ul><li>Library </li></ul></ul><ul><ul><li>Web applications...
瀏覽專案
問題在設計 <ul><li>問題不在你使用什麼 framework </li></ul><ul><li>問題在於你的設計對不對 </li></ul>
劃分出系統架構中的各層 <ul><li>Presentation </li></ul><ul><ul><li>JSP 實作 </li></ul></ul><ul><li>Action </li></ul><ul><ul><li>JSP/Serv...
何謂 Facade <ul><li>Façade 就是建築物正面的入口 </li></ul><ul><li>The Façade pattern simplifies access to a related sets of objects by...
你需要的只是 Code Gen 嗎? <ul><li>許多 framework 會強調 CRUD 應用程式的快速建立 </li></ul><ul><li>可是… </li></ul><ul><ul><li>許多應用程式的本質並不在 CRUD <...
有些 Web Application 的問題在於 <ul><li>問題在於設計 </li></ul><ul><li>缺乏了 Façade layer </li></ul><ul><li>使用 Struts 之類的 framework 來實作 M...
LWDBA <ul><li>輕量級的資料庫存取( Light-Weight Database Access ) </li></ul><ul><li>目標:簡化存取關聯性資料庫的動作,提供最普遍的資料存取需求 </li></ul><ul><li>...
對資料庫存取的需求 <ul><li>容易設定 </li></ul><ul><li>支援 Connection Pooling </li></ul><ul><li>簡化 SQL 操作 </li></ul><ul><li>簡易的 DAO </li>...
資料庫的設定 <ul><li>記錄於 CLASSPATH 中的 system.properties </li></ul>lwdb.pool.default.type=mysql lwdb.pool.default.driverClassName...
LWDBA 對 SQL 的態度 <ul><li>一般人不在程式中使用 SQL 的原因? </li></ul><ul><ul><li>資料庫相依性 </li></ul></ul><ul><ul><li>schema change 帶來的影響 </...
SQL 操作 - DBRow (1/3) <ul><li>tw.qing.lwdba.DBRow </li></ul><ul><li>public DBRow(String _tableName, String _pkName) </li></...
SQL 操作 - DBRow (2/3) <ul><li>public String toInsertString() </li></ul><ul><li>public String toDeleteString() </li></ul><ul...
SQL 操作 - DBRow (3/3) DBRow dr = new DBRow(&quot;Customer&quot;, &quot;seqNo&quot;); dr.setColumn(&quot;name&quot;, name); ...
SQL 操作 - SQLManager (1/4) <ul><li>SQLManager 是 lwdba 為了避免將 SQL 敘述 hardcode 在程式中的類別 </li></ul><ul><li>SQLManager 會依據 system...
SQL 操作 - SQLManager (2/4) <ul><li>SQL 設定檔中的每一行文字行皆代表一組 SQL 敘述,並且皆為 name=value 的對應 </li></ul><ul><ul><li>例如: user.getUserPa...
SQL 操作 - SQLManager (3/4) <ul><li>SQL 敘述的命名,除了 SQL 敘述本身的意義之外,在前頭冠上子系統(對應至 Facade )的名稱 </li></ul><ul><li>SQL 敘述中如果有參數的部份,是程...
SQL 操作 - SQLManager (4/4) <ul><li>SQLManager 提供 getSQL() 族系的方法來取得 SQL 設定檔的內容 </li></ul><ul><ul><li>String getSQL(String ke...
存取 Database  -  DBFacade <ul><li>tw.qing.lwdba.DBFacade </li></ul><ul><li>DBFacade() </li></ul><ul><li>DBFacade(String poo...
查詢結果 -  QueryResult <ul><li>tw.qing.lwdba.QueryResult </li></ul><ul><li>public ArrayList getRows() </li></ul><ul><li>publi...
取得查詢結果 <ul><li>LWDBA 將查詢結果置於 ArrayList 中 </li></ul><ul><li>ArrayList 中的每個元素都是 HashMap </li></ul><ul><ul><li>用 HashMap 表示 R...
取得查詢結果 - 範例 StatisticsFacade facade = StatisticsFacade.getInstance(); ArrayList al = PPTVStatisticsFacade.listStatistics(n...
基於 LWDBA 的設計 <ul><li>依據資料的處理特性,劃分你的子系統 </li></ul><ul><ul><li>AdFacade </li></ul></ul><ul><ul><li>AnnouncementFacade </li><...
撰寫 Facade <ul><li>繼承自 DBFacade </li></ul><ul><li>參考 PPTVStatisticsFacade </li></ul>
使用 Façade 的優點 <ul><li>將事務邏輯封裝於特定的層次 </li></ul><ul><li>Action class 不再充斥著事務邏輯 </li></ul><ul><ul><li>降低相依性 </li></ul></ul><u...
Thanks! Q&A
Upcoming SlideShare
Loading in...5
×

山頂洞人日記 - 回歸到最純樸的開發

3,658

Published on

2008/05/17 TWJUG slides

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,658
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
49
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

山頂洞人日記 - 回歸到最純樸的開發

  1. 1. 山頂洞人日記 - 回歸到最純樸的開發 王建興 qing@cs.nthu.edu.tw (Email/MSN) twitter://qing_wang http://blog.qing.tw 2008/5/16
  2. 2. 審視你的需求 <ul><li>慾望總是超過真實需求 </li></ul><ul><li>威力強大的東西難免複雜 </li></ul><ul><li>選擇開發工具要在複雜度與威力之間選擇一個適合你的平衡點 </li></ul>
  3. 3. 山頂洞人過的日子 <ul><li>WinCVS </li></ul><ul><li>EditPlus </li></ul><ul><li>Ant </li></ul><ul><li>MySQL </li></ul><ul><li>Tomcat </li></ul><ul><li>JavaDoc of API </li></ul>
  4. 4. 簡易級 Java Web 應用程式開發 <ul><li>不用 IDE </li></ul><ul><ul><li>用 Editplus 來編輯原始碼 </li></ul></ul><ul><ul><li>用 WinCVS 來做 project browsing </li></ul></ul><ul><ul><li>用 Ant 來做自動化建構 </li></ul></ul><ul><li>用 JSP 來寫 action </li></ul><ul><ul><li>不用 Struts </li></ul></ul><ul><ul><li>不用 Spring </li></ul></ul><ul><li>利用 LWDBA 來存取資料庫 </li></ul><ul><ul><li>不用 Hibernate </li></ul></ul><ul><ul><li>不用 EJB </li></ul></ul>
  5. 5. 關於 Ant <ul><li>為各種類型的專案建立不同 build.xml 的 template </li></ul><ul><ul><li>Library </li></ul></ul><ul><ul><li>Web applications </li></ul></ul><ul><ul><li>Standalone application </li></ul></ul><ul><li>每次建立新的專案時,依照 template 建立固定的目錄結構 </li></ul>
  6. 6. 瀏覽專案
  7. 7. 問題在設計 <ul><li>問題不在你使用什麼 framework </li></ul><ul><li>問題在於你的設計對不對 </li></ul>
  8. 8. 劃分出系統架構中的各層 <ul><li>Presentation </li></ul><ul><ul><li>JSP 實作 </li></ul></ul><ul><li>Action </li></ul><ul><ul><li>JSP/Servlet 實作 </li></ul></ul><ul><ul><li>使用 JSP 的優點在於 script language 的動態優勢 </li></ul></ul><ul><li>Façade </li></ul><ul><ul><li>封裝事務邏輯 </li></ul></ul><ul><ul><li>一般人最欠缺的 </li></ul></ul><ul><li>Data Access Layer </li></ul><ul><ul><li>LWDBA </li></ul></ul>
  9. 9. 何謂 Facade <ul><li>Façade 就是建築物正面的入口 </li></ul><ul><li>The Façade pattern simplifies access to a related sets of objects by providing one object that all objects outside the set use to communicate with the set. </li></ul>
  10. 10. 你需要的只是 Code Gen 嗎? <ul><li>許多 framework 會強調 CRUD 應用程式的快速建立 </li></ul><ul><li>可是… </li></ul><ul><ul><li>許多應用程式的本質並不在 CRUD </li></ul></ul><ul><li>CRUD 程式碼的快速產生,似乎只對開發 ERP 之類的系統比較有幫助 </li></ul>
  11. 11. 有些 Web Application 的問題在於 <ul><li>問題在於設計 </li></ul><ul><li>缺乏了 Façade layer </li></ul><ul><li>使用 Struts 之類的 framework 來實作 MVC </li></ul><ul><li>使用諸如 Hibernate 的 framework 存取資料 </li></ul><ul><li>事務邏輯未封裝 </li></ul><ul><li>於 Action 類別中直接操作 DAO </li></ul>問題所在
  12. 12. LWDBA <ul><li>輕量級的資料庫存取( Light-Weight Database Access ) </li></ul><ul><li>目標:簡化存取關聯性資料庫的動作,提供最普遍的資料存取需求 </li></ul><ul><li>No ORM, No Code Gen </li></ul>
  13. 13. 對資料庫存取的需求 <ul><li>容易設定 </li></ul><ul><li>支援 Connection Pooling </li></ul><ul><li>簡化 SQL 操作 </li></ul><ul><li>簡易的 DAO </li></ul><ul><li>支援 Query Caching </li></ul>
  14. 14. 資料庫的設定 <ul><li>記錄於 CLASSPATH 中的 system.properties </li></ul>lwdb.pool.default.type=mysql lwdb.pool.default.driverClassName=org.gjt.mm.mysql.Driver lwdb.pool.default.driverURL=jdbc:mysql://localhost:3306/lwdba lwdb.pool.default.userName=root lwdb.pool.default.password=root lwdb.pool.default.maxConnectionCount=32 lwdb.pool.default.encoding=UTF-8 lwdb.pool.default.sqlFile=sql
  15. 15. LWDBA 對 SQL 的態度 <ul><li>一般人不在程式中使用 SQL 的原因? </li></ul><ul><ul><li>資料庫相依性 </li></ul></ul><ul><ul><li>schema change 帶來的影響 </li></ul></ul><ul><li>LWDBA 對 SQL statement 的觀點 </li></ul><ul><ul><li>在程式中使用 SQL statement </li></ul></ul><ul><ul><li>但在程式中看不到 SQL statement </li></ul></ul><ul><li>做法 </li></ul><ul><ul><li>SQL statement composer </li></ul></ul><ul><ul><li>SQL 抽離至外部的設定檔 </li></ul></ul>
  16. 16. SQL 操作 - DBRow (1/3) <ul><li>tw.qing.lwdba.DBRow </li></ul><ul><li>public DBRow(String _tableName, String _pkName) </li></ul><ul><li>public DBRow(String _tableName, String _pkName[]) </li></ul><ul><li>public void setColumn(String columnName, Object value) </li></ul><ul><li>public Object getColumn(String columnName) </li></ul><ul><li>public void removeColumn(String columnName) </li></ul><ul><li>public HashMap getRow() </li></ul><ul><li>public void setRow(HashMap hm) </li></ul>
  17. 17. SQL 操作 - DBRow (2/3) <ul><li>public String toInsertString() </li></ul><ul><li>public String toDeleteString() </li></ul><ul><li>public String toUpdateString() </li></ul><ul><li>public String toQueryString() </li></ul>
  18. 18. SQL 操作 - DBRow (3/3) DBRow dr = new DBRow(&quot;Customer&quot;, &quot;seqNo&quot;); dr.setColumn(&quot;name&quot;, name); dr.setColumn(&quot;phone&quot;, phone); dr.setColumn(&quot;address&quot;, address); System.out.println(dr.toInsertString());
  19. 19. SQL 操作 - SQLManager (1/4) <ul><li>SQLManager 是 lwdba 為了避免將 SQL 敘述 hardcode 在程式中的類別 </li></ul><ul><li>SQLManager 會依據 system.properties 中所設定的 sqlFile 來決定實際使用的 SQL 敘述設定檔 </li></ul><ul><ul><li>例如: sql.properties </li></ul></ul><ul><li>針對不同的資料庫組態,都提供一份外掛的 SQL 敘述設定檔 </li></ul><ul><li>程式中若想使用 SQL 敘述,則務必透過 SQLManager 來取得 SQL 敘述 </li></ul><ul><li>當系統欲切換所使用的資料庫類型時,便毋需徹底修改程式中漫於四處的 SQL 敘述 </li></ul>
  20. 20. SQL 操作 - SQLManager (2/4) <ul><li>SQL 設定檔中的每一行文字行皆代表一組 SQL 敘述,並且皆為 name=value 的對應 </li></ul><ul><ul><li>例如: user.getUserPassword=select password from UserAccount where id={0} </li></ul></ul>
  21. 21. SQL 操作 - SQLManager (3/4) <ul><li>SQL 敘述的命名,除了 SQL 敘述本身的意義之外,在前頭冠上子系統(對應至 Facade )的名稱 </li></ul><ul><li>SQL 敘述中如果有參數的部份,是程式執行過程中動態傳入的,以 {0} 、 {1} 、…、 {n} 來依序代表傳入的第 0 個、第 1 個、以及第 n 個參數 </li></ul><ul><li>在撰寫 SQL 敘述時,大小寫有別 </li></ul>
  22. 22. SQL 操作 - SQLManager (4/4) <ul><li>SQLManager 提供 getSQL() 族系的方法來取得 SQL 設定檔的內容 </li></ul><ul><ul><li>String getSQL(String key) </li></ul></ul><ul><ul><li>String getSQL(String key, Object arg) </li></ul></ul><ul><ul><li>String getSQL(String key, Object arg1, Object arg2) </li></ul></ul><ul><ul><li>String getSQL(String key, Object arg1, Object arg2, Object arg3) </li></ul></ul><ul><ul><li>String getSQL(String key, Object arg1, Object arg2, Object arg3, Object arg4) </li></ul></ul><ul><ul><li>String getSQL(String key, Object[] arg) </li></ul></ul>
  23. 23. 存取 Database - DBFacade <ul><li>tw.qing.lwdba.DBFacade </li></ul><ul><li>DBFacade() </li></ul><ul><li>DBFacade(String poolName) </li></ul><ul><li>public QueryResult sqlQuery(String query) </li></ul><ul><li>public int sqlUpdate(String update) </li></ul><ul><li>public QueryResult sqlQuery(String query, int idxRow, int count, boolean fReturnTotal) </li></ul><ul><li>public ArrayList sqlQueryRows(String query) </li></ul><ul><li>public ArrayList sqlQueryRows(String query, int idxRow, int count) </li></ul>
  24. 24. 查詢結果 - QueryResult <ul><li>tw.qing.lwdba.QueryResult </li></ul><ul><li>public ArrayList getRows() </li></ul><ul><li>public int getTotalRowCount() </li></ul>
  25. 25. 取得查詢結果 <ul><li>LWDBA 將查詢結果置於 ArrayList 中 </li></ul><ul><li>ArrayList 中的每個元素都是 HashMap </li></ul><ul><ul><li>用 HashMap 表示 ResultSet 中的一筆結果 </li></ul></ul><ul><li>HashMap 即為通用性質的 DAO </li></ul><ul><li>可直接將 ArrayList 及 HashMap 整合快取系統 </li></ul>
  26. 26. 取得查詢結果 - 範例 StatisticsFacade facade = StatisticsFacade.getInstance(); ArrayList al = PPTVStatisticsFacade.listStatistics(n); <% for(int i=0;i<al.size();i++) { HashMap hm = (HashMap) al.get(i); %> <tr> <td><%=hm.get(&quot;seqNo&quot;)%></td> <td><%=hm.get(&quot;uid&quot;)%></td> <td><%=hm.get(&quot;remoteHost&quot;)%></td> <td><%=hm.get(&quot;type&quot;)%></td> <td><%=hm.get(&quot;createTime&quot;)%></td> </tr> <% } %>
  27. 27. 基於 LWDBA 的設計 <ul><li>依據資料的處理特性,劃分你的子系統 </li></ul><ul><ul><li>AdFacade </li></ul></ul><ul><ul><li>AnnouncementFacade </li></ul></ul><ul><ul><li>HotelFacade </li></ul></ul><ul><ul><li>MemberFacade </li></ul></ul><ul><ul><li>OrderFacade </li></ul></ul><ul><ul><li>ZipCodeFacade </li></ul></ul><ul><ul><li>… </li></ul></ul>
  28. 28. 撰寫 Facade <ul><li>繼承自 DBFacade </li></ul><ul><li>參考 PPTVStatisticsFacade </li></ul>
  29. 29. 使用 Façade 的優點 <ul><li>將事務邏輯封裝於特定的層次 </li></ul><ul><li>Action class 不再充斥著事務邏輯 </li></ul><ul><ul><li>降低相依性 </li></ul></ul><ul><ul><li>提昇因為變動所造成的影響 </li></ul></ul><ul><li>Action class 所面對的是 business service ,而非直接操作資料 </li></ul>
  30. 30. Thanks! Q&A
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×