初學者關於介面編程的認識

來源:互聯網
上載者:User

首先,先聲明一下,我是一名學生,程式碼屈指可數,所談之處只是個人的見解,錯的地方希望大家多多指點,先謝謝大家~

 

大三一次很幸運的機會,參加了一次外面培訓,當時的老師提到了一個概念就是:面向介面編程。但是當時老師因為時間的問題,沒有展開給我們講解,只是讓我們看了一下他的應用,後來自己多次模仿。其實,操作很簡單,當你想建立一個類的時候,就把類中公有的方法抽象到介面中,然後定義一個名字。

有一天,我發現這個過程很麻煩,因為每次我要修改參數的時候,都要先修改介面,然後再修改類,而我這個介面貌似只是針對這一個類的,如果沒有它,我的這個程式是依然可以完成的,然後,我毅然決然的就不再使用介面了。後來,才知道是自己沒有真正理解“面向介面編程”的真正意義。

 

大三的下學期,依然是去參加培訓,這次時間比較短暫,所接觸的知識就是由java到web的學習——jsp的簡單應用。關於知識沒有學到多少,但是老師在整個過程中,一直給我們強調了一個關於編程過程的問題,後來老師提到了一本叫“重構”的書。對於編碼,首先應該是想辦法把問題解決,然後把看得不舒服的位置,仔細思考,然後進行修改,更換些簡便舒服的程式碼片段。

實習結束之後,自己厚著臉皮買了這本叫“重構——改善既有代碼的設計”,為什麼說厚著臉,因為總覺得只有程式碼達到一定量之後,才能完成代碼的最佳化美觀。後來自己讀了,書上介紹的過程也大致就是老師講解的意思,因為自己的能力有限還沒有真正理解書中的高深技術,但是在自己編程中,有的時候自己也略微整理一下自己的代碼,慢慢的,我發現自己喜歡上abstract class這個東西了,每次結構相似的抽象一下整理出一個父類,然後把其中的代碼分功能模組的整理。

 

隨著編碼越來越多,自己開始頻繁的使用資料庫,大家也都知道,在資料庫連接中,更新操作,代碼的樣子都差不多,每次不同的只是從資料庫中尋找對象,於是自己寫了一個這樣的抽象類別,以供不同的實體類繼承。public abstract class ExecSql<E> {</p><p>/**<br /> * 資料庫連接<br /> */<br />protected Connection conn = null;</p><p>/**<br /> * 資料庫操作<br /> */<br />protected Statement stmt = null;</p><p>/**<br /> * 資料庫先行編譯操作<br /> */<br />protected PreparedStatement pstmt = null;</p><p>/**<br /> * 結果集<br /> */<br />protected ResultSet rs = null;</p><p>/**<br /> * 從結果集中擷取資訊<br /> * @function:從結果集中讀取一條資訊,並以執行個體的格式返回<br /> * @return 對象執行個體<br /> * @author: 豔沐石 2010-10-17 下午02:13:09<br /> * @throws SQLException<br /> */<br />protected abstract E getInfoFromResultSet() throws SQLException;</p><p>/**<br /> * 獲得簡單的資料庫查詢語句<br /> * @return<br /> */<br />protected abstract String createBaseQuerySql();</p><p>/**<br /> * 查詢資訊集合<br /> * @function:使用Statement操作,將滿足條件的資訊以集合的形式返回<br /> * @param sql 資料庫語句<br /> * @return 查詢結果的集合<br /> * @author: 豔沐石 2010-10-17 下午02:14:17<br /> */<br />public List<E> getAllInfosByStatement(String sql) {<br />List<E> list = new ArrayList<E>();</p><p>try {<br />getResultSetByStatement(sql);</p><p>// 將結果集中的資料讀取出來,存入到集合中<br />while (rs.next()) {<br />list.add(getInfoFromResultSet());<br />}<br />} catch (SQLException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />} finally {<br />DBConnection.close(rs, stmt, conn);<br />}</p><p>return list;<br />}</p><p>/**<br /> * 從結果集中讀取一條資訊<br /> * @function:使用Statement操作,讀取合格第一條資訊<br /> * @param sql 資料庫語句<br /> * @return 對象執行個體<br /> * @author: 豔沐石 2010-10-17 下午02:15:15<br /> */<br />public E getInfoByStatement(String sql) {<br />E e = null;</p><p>try {<br />getResultSetByStatement(sql);</p><p>// 讀取獲得結果資訊<br />if (rs.next()) {<br />e = getInfoByStatement(sql);<br />}<br />} catch (SQLException e1) {<br />// TODO Auto-generated catch block<br />e1.printStackTrace();<br />} finally {<br />DBConnection.close(rs, stmt, conn);<br />}</p><p>return e;<br />}</p><p>/**<br /> * 查詢資訊集合<br /> * @function:使用PreparedStatment操作,將滿足條件的資訊以集合的形式返回<br /> * @param sql 資料庫語句<br /> * @param values 限制條件的值<br /> * @return 資訊集合<br /> * @author: 豔沐石 2010-10-17 下午02:16:37<br /> */<br />public List<E> getAllInfosByPreparedStatement(String sql, List<Object> values) {<br />List<E> list = new ArrayList<E>();</p><p>try {<br />getResultSetByPreparedStatement(sql, values);</p><p>// 將結果集中的資訊添加到集合中<br />while (rs.next()) {<br />list.add(getInfoFromResultSet());<br />}<br />} catch (SQLException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />} finally {<br />DBConnection.close(rs, pstmt, conn);<br />}</p><p>return list;<br />}</p><p>/**<br /> * 從結果集中讀取一條資訊<br /> * @function:使用PreparedStatement操作,讀取一條滿足條件的資訊,以執行個體形式返回<br /> * @param sql 資料庫語句<br /> * @param values 限制條件的值<br /> * @return 對象執行個體<br /> * @author: 豔沐石 2010-10-17 下午02:18:04<br /> */<br />public E getInfoByPreparedStatement(String sql, List<Object> values) {<br />E e = null;</p><p>try {<br />getResultSetByPreparedStatement(sql, values);</p><p>if (rs.next()) {<br />e = getInfoFromResultSet();<br />}<br />} catch (SQLException e1) {<br />// TODO Auto-generated catch block<br />e1.printStackTrace();<br />} finally {<br />DBConnection.close(rs, pstmt, conn);<br />}</p><p>return e;<br />}</p><p>/**<br /> * 資料庫更新<br /> * @function:使用Statement操作,更新資料庫資訊<br /> * @param sql 資料庫語句<br /> * @return 受影響的行數<br /> * @author: 豔沐石 2010-10-17 下午02:19:25<br /> */<br />public int updateInfosByStatement(String sql) {<br />int count = 0;</p><p>try {<br />confStatement();</p><p>// 執行更新,並記錄影響行數<br />count = stmt.executeUpdate(sql);<br />} catch (SQLException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />} finally {<br />DBConnection.close(stmt, conn);<br />}</p><p>return count;<br />}</p><p>/**<br /> * 資料庫更新<br /> * @function:使用PreparedStatement操作,更新資料庫資訊<br /> * @param sql 資料庫語句<br /> * @param values 限制條件的值<br /> * @return 受影響的行數<br /> * @author: 豔沐石 2010-10-17 下午02:20:30<br /> */<br />public int updateInfosByPreparedStatement(String sql, List<Object> values) {<br />int count = 0;</p><p>try {<br />confPreparedStatement(sql, values);</p><p>// 執行更新,並記錄影響行數<br />count = pstmt.executeUpdate();<br />} catch (SQLException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />} finally {<br />DBConnection.close(pstmt, conn);<br />}</p><p>return count;<br />}</p><p>/**<br /> * 批處理更新資料庫<br /> * @function:處理一批資料庫更新操作<br /> * @param sqls 資料庫語句組(數組)<br /> * @return 每條更新所影響的資料庫行數<br /> * @author: 豔沐石 2010-10-17 下午02:22:31<br /> */<br />public int[] updateInfosByStatementBatch(String[] sqls) {<br />int[] count = null;</p><p>try {<br />confStatement();</p><p>// 將需要執行的語句添加到批處理操作中<br />for (String sql : sqls) {<br />stmt.addBatch(sql);<br />}</p><p>// 批處理執行<br />count = stmt.executeBatch();<br />} catch (SQLException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />} finally {<br />DBConnection.close(stmt, conn);<br />}</p><p>return count;<br />}</p><p>/**<br /> * 批處理更新資料庫<br /> * @function:處理一批資料庫更新操作<br /> * @param sqls 資料庫語句組(集合)<br /> * @return 每條更新所影響的資料庫行數<br /> * @author: 豔沐石 2010-10-17 下午02:24:27<br /> */<br />public int[] updateInfosByStatementBatch(List<String> sqls) {<br />return updateInfosByStatementBatch((String[])sqls.toArray());<br />}</p><p>/**<br /> * 獲得結果集<br /> * @function:使用Statement操作,擷取查詢的結果集<br /> * @param sql 資料庫語句<br /> * @throws SQLException 資料庫操作異常<br /> * @author: 豔沐石 2010-10-17 下午02:25:41<br /> */<br />protected void getResultSetByStatement(String sql) throws SQLException {<br />confStatement();</p><p>rs = stmt.executeQuery(sql);<br />}</p><p>/**<br /> * 獲得結果集<br /> * @function:使用PreparedStatement操作,擷取查詢的結果集<br /> * @param sql 資料庫語句<br /> * @param values 限制條件的值<br /> * @throws SQLException 資料庫操作異常<br /> * @author: 豔沐石 2010-10-17 下午02:26:21<br /> */<br />protected void getResultSetByPreparedStatement(String sql, List<Object> values) throws SQLException {<br />confPreparedStatement(sql, values);</p><p>rs = pstmt.executeQuery();<br />}</p><p>/**<br /> * 配置Statement操作<br /> * @function:串連資料庫,並獲得資料庫操作<br /> * @throws SQLException 資料庫操作異常<br /> * @author: 豔沐石 2010-10-17 下午02:27:02<br /> */<br />protected void confStatement() throws SQLException {<br />confConnectiong();</p><p>stmt = conn.createStatement();</p><p>System.out.println(stmt);<br />}</p><p>/**<br /> * 配置PreparedStatement操作<br /> * @function:串連資料庫,並將產生先行編譯處理操作<br /> * @param sql 資料庫語句<br /> * @param values 限制條件的值<br /> * @throws SQLException 資料庫操作異常<br /> * @author: 豔沐石 2010-10-17 下午02:27:30<br /> */<br />protected void confPreparedStatement(String sql, List<Object> values) throws SQLException {<br />confConnectiong();</p><p>pstmt = conn.prepareStatement(sql);</p><p>if (values != null) {<br />for (int i = 0; i < values.size(); i++) {<br />pstmt.setObject(i+1, values.get(i));<br />}<br />}</p><p>System.out.println(pstmt);<br />}</p><p>/**<br /> * 設定資料庫串連<br /> * @function:獲得一個資料庫連接<br /> * @author: 豔沐石 2010-10-17 下午02:29:00<br /> */<br />protected void confConnectiong() {<br />conn = DBConnection.getConnection();<br />}<br />}<br />

這樣,當我對不同的實體類就可以是指實現getInfoFromResultSet方法了。

 

隨著時光的推進,在大四,我接觸到了流行的SSH架構,大三下學期的時候,同學就鼓勵我看看架構,可是自己總覺得自己基礎知識還沒到位,於是自己學習了關於設計模式,編程規範,重構等方面的東西,自己覺得自己還是有些收穫,但是跟自己程式碼還是有很大的關係。自己也寫了幾個關於Spring的程式,這個時候,只是知道Spring大量使用面向介面編程,自己也沒太明白。後來,同學給自己介紹的時候,我依然覺得不用介面也可以啊,後來自己還專門寫了一個抽象類別,以用來減少代碼的冗餘:

package com.cms.service;</p><p>import java.util.List;</p><p>import org.hibernate.Query;<br />import org.hibernate.Session;<br />import org.hibernate.SessionFactory;</p><p>public abstract class AbstractService<E> {</p><p>protected SessionFactory sessionFactory = null;</p><p>/**<br /> * @return the sessionFactory<br /> */<br />public SessionFactory getSessionFactory() {<br />return sessionFactory;<br />}</p><p>/**<br /> * @param sessionFactory the sessionFactory to set<br /> */<br />public void setSessionFactory(SessionFactory sessionFactory) {<br />this.sessionFactory = sessionFactory;<br />}</p><p>/**<br /> * @return 獲得當前會話<br /> */<br />public Session getSession() {<br />return getSessionFactory().getCurrentSession();<br />}</p><p>/**<br /> * @param hql 需要執行的hql語句<br /> * @return the query 封裝好的Query對象<br /> */<br />public Query getQuery(String hql) {<br />return getSession().createQuery(hql);<br />}</p><p>/*<br /> * 根據id獲得資訊<br /> */<br />public abstract E getInfo(int id);</p><p> /*<br /> * 批量擷取資訊<br /> */<br />public abstract List<E> getInfos(int currentPage, int pagesize);</p><p>/*<br /> * 根據id刪除<br /> */<br />public void delete(int id) {<br />getSession().delete(id);<br />}</p><p>/*<br /> * 儲存<br /> */<br />public void save(E e) {<br />getSession().save(e);<br />}</p><p>/*<br /> * 更新<br /> */<br />public void update(E e) {<br />getSession().update(e);<br />}</p><p>/**<br /> * @param q the query<br /> * @param currentPage the current page num<br /> * @param pagesize the count of a page<br /> */<br />protected void confQuery(Query q, int currentPage, int pagesize) {<br />q.setFirstResult(firstLocation(currentPage, pagesize));<br />q.setMaxResults(pagesize);<br />}</p><p>/**<br /> * @param q the query<br /> * @return the result list<br /> */<br />@SuppressWarnings("unchecked")<br />protected List<E> list(Query q) {<br />List<E> list = q.list();</p><p>return list;<br />}</p><p>/*<br /> * get the first record location<br /> */<br />private int firstLocation(int currentPage, int pagesize) {<br />return (currentPage - 1) * pagesize;<br />}</p><p>}

 

最近,自己在一次與具有豐富經驗的前輩聊天的時候,談到了面向介面編程這個概念,也是通過他的講解,自己發現,自己存在著很大的問題。所謂的面向介面編程,就像蓋房子似的,介面是房屋的架子,而架子裡放的東西是什麼,也就是實現這個架子的類,我們像擺積木一樣的,把自己需要的實作類別放到指定的位置,這也就是Spring設定檔的意思,當有一天,我們需要升級系統的時候,有些實作類別過時了,不再需要的時候,我們只需要把新的實作類別替換舊的實作類別,這樣,每次修改,都只需要做小幅度的調整。而面向介面編程的一個重要目的不是為了首次開發帶來方便的,而是為以後維護帶來方便的。 

 

仔細思考,發現自己在編程的思想上還很幼稚,對於抽象類別,我完全可以把他抽象一個介面,當作一個工具對象,彙總到另外的類中,這樣我也可以維護這個工具類了。

突然想到了thingking in java第一章的標題:一切都是對象。

 

加油,努力!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.