1. 程式人生 > >DAO層與Service業務邏輯層的解耦實現之Factory工廠模式

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物件的結構:

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;
	}
}
然後,定義一個數據訪問介面UserDao:
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目錄下即可,編譯時會被自動帶過去的),不然就會無法找到該檔案而出現空指標異常。

以上就是本篇部落格。~博主的肚子好餓~抓狂

相關推薦

DAOService業務邏輯實現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  理念