DAO層與Service業務邏輯層的解耦實現之Factory工廠模式
在開始闡述DAO與Service層如何實現解耦之前,我先提一個站在學習者角度的問題,為什麼在MVC的三層開發架構中會非常推崇介面程式設計,那麼根據已有的解釋,介面程式設計的好處是:可以幫助層與層之間的解耦,讓每個部分獨立出來,互不影響,更加的利於團隊開發合作和提高複用性與擴充套件性。那麼,在資料訪問層(DAO)和業務層(SERVICE)之間的解耦是如何做到的呢?下面請先看一張框架簡圖:
不難發現的是,UserService是通過介面UserDao來間接操作UserDaoImpl訪問Domain物件User中的資料的。有些程式設計經驗的童鞋都應該明白,要想拿到具體的實現,那麼這種操作(先不管紅色部分的UserDaoFactory工廠類),在訪問User時就必定要在UserService中有這樣的語句:UserDao userDao = new UserDaoImpl(); 那麼,問題來了, UserDaoImpl實現類在這裡出現並將導致在後期拓展時(比如UserDao的具體實現改換為Hibernate或者其它技術)就無法真正的做到解耦,因為你必須在你的原始碼中指定具體的實現類。如果這裡,你還沒有明白,那麼請看以下程式碼:
首先,我們來構造一個Domain域物件User,此User在此其實並沒有多大意義只是為了展示Domain物件的結構:
然後,定義一個數據訪問介面UserDao:package com.jasber.jdbc.test1; import java.util.Date; /** * This is Bean that corresponding int Mysql database table tb_test * * @author Jasber-Yon * */ public class User { private Integer id; private String name; private Date birthday; private Double salary; public User() { } public User(Integer id, String name, Date birthday, Double salary) { super(); this.id = id; this.name = name; this.birthday = birthday; this.salary = salary; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } }
package com.jasber.jdbc.test1;
/**
*
* @author Jasber-Yon
*
*/
public interface UserDao {
public boolean getUserInfoById(User user);
}
現在,就來實現這個UserDao資料訪問介面,實現類UserDaoImpl(在這裡就不做真正的實現了,只為說明問題):package com.jasber.jdbc.test1; public class UserDaoImpl implements UserDao { @Override public boolean getUserInfoById(User user) { //.....程式碼省略 System.out.println("哈哈,我被呼叫了~"); return false; } }
那麼,現在,我們可以寫一個UserService來模擬一下呼叫了:
package com.jasber.jdbc.test1;
/**
*
* @author Jasber-Yon
*
*/
public class UserService {
public static void main(String[] args) {
User user = new User();
UserDao userDao = new UserDaoImpl();
userDao.getUserInfoById(user);
}
}
現在,就會發現,UserDaoImpl 在UserService中被“點名”了,這樣幹,顯然是不合理的,沒有做到真的解耦,我們的目的是,要讓UserService僅僅只需要通過資料訪問介面UserDao就做到需要的操作。那麼,應該如何來做呢?
一、提供一個工廠類,讓他去對具體的實現類進行例項化,並返回UserDao的實現類的例項的引用。
二、這個資料訪問介面的實現類在哪兒呢?通過配置檔案(XML/Properties,我偷個懶就使用properties檔案了)來配置,讓工廠類去讀取(或者專用的操作類去讀取)。
那麼,請看這個工廠類UserDaoFactory的實現:
package com.jasber.jdbc.test1;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class UserDaoFactory {
private static UserDao userDao = null;// 注意此句必須放在例項化工廠類的語句之前,否者會在執行時被置為null
private static UserDaoFactory userDaoFactory = new UserDaoFactory();
private UserDaoFactory() {
Properties properties = new Properties();
InputStream inputStream = UserDaoFactory.class.getClassLoader()
.getResourceAsStream("daoConfig.properties");
try {
properties.load(inputStream);
String userDaoImpl = properties.getProperty("userDaoImpl");
userDao = (UserDao) Class.forName(userDaoImpl).newInstance();
} catch (Throwable e) {
throw new ExceptionInInitializerError(e);// 此問題非常嚴重
}finally{
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static UserDaoFactory getInstance() {
return userDaoFactory;
}
public UserDao getUserDao() {
return userDao;
}
}
通過類載入器,獲得到實現類的位置,然後通過反射技術將其例項化。在此工廠(單例實現,懶漢式直接載入,也可延遲載入)類中將提供返回工廠例項的方法以及資料訪問介面UserDao的實現類的例項。
現在再來看看,我們是怎樣在UserService中來操作資料訪問物件(DAO)的:
package com.jasber.jdbc.test1;
/**
*
* @author Jasber-Yon
*
*/
public class UserService {
public static void main(String[] args) {
/*User user = new User();
UserDao userDao = new UserDaoImpl();
userDao.getUserInfoById(user);*/
User user = new User();
UserDao userDao = UserDaoFactory.getInstance().getUserDao();
userDao.getUserInfoById(user);
}
}
與註釋部分對比,不難發現,已經沒有了UserDaoImpl的蹤影。完全是在操作介面了。是不是就已經解耦了呢?
想必,到這兒,已經明白是怎麼回事了。下面在說一說,我在程式中使用到的 daoConfig.properties 檔案(我是偷懶了啊,當然這樣也是為了簡化程式碼保證闡述問題的單純性,就沒有使用XML來說事),因為我們使用到了類載入器,該配置檔案必須要放置在ClassPath路徑下(當然位置是隨意的,ClassPath路徑就是指執行程式時,會被JVM讀取載入的目錄,也就是bin目錄下,Java工程裡,使用eclipse的就直接放在src目錄下即可,編譯時會被自動帶過去的),不然就會無法找到該檔案而出現空指標異常。
以上就是本篇部落格。~博主的肚子好餓~
相關推薦
DAO層與Service業務邏輯層的解耦實現之Factory工廠模式
在開始闡述DAO與Service層如何實現解耦之前,我先提一個站在學習者角度的問題,為什麼在MVC的三層開發架構中會非常推崇介面程式設計,那麼根據已有的解釋,介面程式設計的好處是:可以幫助層與層之間的解耦,讓每個部分獨立出來,互不影響,更加的利於團隊開發合作和提高複用性與擴
【ssm框架】Service業務邏輯層&&Mybatis對映層
Service層 通常業務處理的程式碼並不直接放在controller層中,那樣會顯得職責不單一,不方便維護。Service業務邏輯層通常用來處理各種各樣的業務邏輯。我們將最基本的增刪改查抽取出來,作
java重試工具庫: 實現業務邏輯與重試邏輯的解耦
對於開發過網路應用程式的程式設計師來說,重試並不陌生,由於網路的擁堵和波動,此刻不能訪問服務的請求,也許過一小段時間就可以正常訪問了。比如下面這段給某個手機號發SMS的虛擬碼:// 傳送SMSpublic boolean sendSMS(String phone, String content){ int r
Spring 之 factory工廠模式的解耦
在實際開發中我們可以把三層的物件都使用配置檔案配置起來,當啟動伺服器應用載入的時候,讓一個類中的 方法通過讀取配置檔案,把這些物件創建出來並存起來。在接下來的使用的時候,直接拿過來用就好了。 那麼,這個讀取配置檔案,建立和獲取三層物件的類就是工廠。 上一小節解耦的思路有 2 個問題: 1
橋接模式的應用之三層架構中的業務邏輯層(BLL)與資料訪問層(DAL)的解耦
各層的作用 ①使用者介面層:只負責顯示和採集使用者操作。 ②業務邏輯層:負責UI和DAL層之間的資料交換,是系統架構中體現核心價值的部分。它關注點主要集中在業務規則的制定、業務流程的實現和業務需求的有關係統設計。它與系統所對應的領域(Domain)有關。也可以做一些如使用
登陸和註冊的service層(業務邏輯層)
package com.wh.servie; import com.wh.dao.LoginDao; public interface LoginService extends LoginDao { } package com.wh.servie; import com.wh
業務邏輯層與中介軟體
中介軟體是什麼,主要職責是什麼 企業中介軟體看作是處理平臺和系統之間的計算機通訊的一種模型。 中介軟體軟體的職責就是對使用服務的系統進行抽象,使得它們不必知道自己所呼叫系統的技術細節。 例子:通過使
OSI七層與TCP/IP五層網絡架構詳解
p地址 tro 簡單 流控 之間 模型 網卡 層次結構 user OSI和TCP/IP是很基礎但又非常重要的網絡基礎知識,理解得透徹對運維工程師來說非常有幫助。今天偶又復習了一下: (1)OSI七層模型 OSI中的層 功能 TCP/IP協議族 應用層 文件傳輸,
業務邏輯層-Transaction Script
存在 default 員工 數據對象 main tcl 維護 esc scala Transaction Script(事務腳本模式),是一種最簡單和最容易接受的處理業務的方法。這種模式是采用面向過程的方式來組織業務邏輯。通常情況下,系統的一個流程會被實現為一個方法,然後所
業務邏輯層
它的 健壯性 關註 空字符 工作 格式 訪問 三層 樣式 業務邏輯層(Business Logic Layer)無疑是系統架構中體現核心價值的部分。它的關註點主要集中在業務規則的制定、業務流程的實現等與業務需求有關的系統設計,也即是說它是與系統所應對的領域(Domain)邏
充值系列——充值系統業務邏輯層實現(三)
上一篇文章主要說明充值的執行邏輯和控制層的設計,這篇文章主要討論充值業務層的具體實現。 正如上一篇文章所說到的,生成訂單需要如下幾個步驟: (1)例項化操作人 (操作人) (2)例項化產品模型 (獲取產品的詳細資訊) (3)例項化訂單模型 (生成一筆狀態為“交易中”的訂單)
OSI七層與TCP/IP五層網路架構詳解
(1)OSI七層模型 OSI中的層 功能 TCP/IP協議族 應用層 檔案傳輸,電子郵件,檔案服務,虛擬終端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示層 資料格式化,程式碼轉換,資料加密 沒有協議 會話層 解除或建立與別的接點的聯絡 沒有協
軟體設計之業務邏輯層設計
業務邏輯層(Business Logic Layer )無疑是系統架構中體現核心價值的部分。它的關注點主要集中在業務規則的制定、業務流程的實現等與業務需求有關的系統設計,也即是說它是與系統所應對的領域(Domain )邏輯有關,很多時候,我們也將業務邏輯層稱為領
springboot配置訪問sqlserver,mysql資料庫以及ssm的公共業務邏輯層抽取
最近喜歡用springboot,有時間就研究了一下,因為經常用sqlserver,在網上查了半天沒有什麼很好的配置,在抽取業務層的時候也出點問題,還好解決了 這是一個比較簡單的結構 先引入sqlserver和mysql的依賴,注意不要重複,這麼低階的錯誤我都不知道
計網--OSI七層與TCP/IP五層網路架構詳解
OSI和TCP/IP是很基礎但又非常重要的網路基礎知識,理解得透徹對運維工程師來說非常有幫助。今天偶又複習了一下: (1)OSI七層模型 OSI中的層 功能 TCP/IP協議族 應用層 檔案傳輸,電子郵件,檔案服務,虛擬終端 TFTP,HTTP,SNMP,FT
檢視層. 控制層, 業務邏輯層, 資料庫訪問層------新認識
程式專案寫了很多了, 總結一下 最初寫的C/S模式的都沒有過分包的習慣, 後來到了B/S的JSP/Servlet/JavaBean , 才知道了分包的意義, 以及模式的概念 . 什麼教View 層 ,什麼叫Model層 ,什麼叫Controller層. 什麼叫業務邏輯
OSI七層與tcp/ip四層
網絡接口 stp data 中繼 進行 數據加密 特殊 還要 網絡 1)OSI七層模型 OSI中的層 功能 TCP/IP協議族 應用層 文件傳輸,電子郵件,文件服務,虛擬終端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示層 數據格式化,代
業務邏輯詳解
企業 控制 數據 rain 邏輯圖 dao 屬性 技術分享 之間 不同的項目有不同的功能,不同的功能需要不同的實現,實現這些核心功能的代碼就叫業務邏輯 比如讓你實現一個功能,給你兩個數,讓你獲取它的和,你所寫的如何才能獲得任意給定的兩個數的和,這個程序實現過程即可成為業務邏
Linux中斷(interrupt)子系統之四:驅動程式介面層 & 中斷通用邏輯層
轉載地址:https://blog.csdn.net/DroidPhone/article/details/7497787 在本系列文章的第一篇:Linux中斷(interrupt)子系統之一:中斷系統基本原理,我把通用中斷子系統分為了4個層次,其中的驅動程式介面層和中斷通用邏輯層的界限實際上不
SOA中的介面劃分與系統模組間的解耦,和通訊
最近要做xxx管理系統產品的時候,需要達到以下要求,可以根據不同客戶的不同需求,將已經開發好的模組無縫的新增,和刪除。 經過技術分析需要 採用以下技術: 1.SOA 理念