久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

解耦解釋(解耦是什么)

344次閱讀
沒有評論

共計 4316 個字符,預計需要花費 11 分鐘才能閱讀完成。

推薦學習:

這可能是全網 Java 學習路線最完整,最詳細的版本了,沒有之一

1、聊聊解耦?

耦合:代碼之間的關聯關系稱為耦合,具有強關聯關系的稱為強耦合。

解耦:解除代碼之間的關聯關系,使每個業務代碼職責單一,目的明確,通常我們在業務上稱為解耦。

2、代碼示例

我們以傳統的 EJB 開發模式為例子,先不以框架展示,大家可以看看一些改代碼難受的場景。

業務來了:我需要把一段數據保存到 mysql 數據庫中,按照分層邏輯實現(controller,service,dao)

Dao 接口層:

publicinterfaceUserDao{

/**

* 保存的接口方法

*/

voidsave();

}

Dao 的 mysql 實現:

publicclassUserDaoMysqlImplimplementsUserDao{

@Override

publicvoidsave() {

System.out.println(“ 保存 mysql 數據庫成功!”);

}

}

Service 接口層:

publicinterfaceUserService{

/**

* 業務接口保存方法

*/

voidsave();

}

Service 的實現:

publicclassUserServiceImplimplementsUserService{

// 業務層調用數據 dao 層,這里不解釋了

privateUserDao userDao =newUserDaoMysqlImpl();

@Override

publicvoidsave() {

userDao.save();

}

}

Controller 視圖層:

publicclassUserController{

privateUserService userService =newUserServiceImpl();

publicvoidsave(){

userService.save();

}

}

很明顯,我們已經實現了業務功能:保存一段數據進 mysql 數據庫

這個時候,你的產品經理說,客戶 mysql 壞了,剛裝了個 oracle,你再改改吧?

然后你這個時候也就加個 oracle,實際上不費時,需求我們再補充下

現在需求:保存一段數據,可以保存在 mysql,也可以保存在 oracle

上面已經有 mysql 代碼了,我們可以知道,我需要增加個 dao 的實現,稱為 UserDaoOracleImpl

上代碼先:

publicclassUserDaoOracleImplimplementsUserDao{

@Override

publicvoidsave() {

System.out.println(“ 保存 oracle 數據庫成功!”);

}

}

ok 我們還要改一個地方,就是 UserServiceImpl,之前父類接口指向的子類引用要改成 oracle

publicclassUserServiceImplimplementsUserService{

// 業務層調用數據 dao 層,這里不解釋了

// private UserDao userDao = new UserDaoMysqlImpl();

privateUserDao userDao =newUserDaoOracleImpl();

@Override

publicvoidsave() {

userDao.save();

}

}

我們發現,在目前的需求形式上,dao 的擴展我們是一定會需要改的,因為滿足多態的特性,但是我們增加一個 dao 層的某個業務,連 service 業務層代碼也要動,你想想,如果業務層代碼達到了上千,即便你有了注釋,改了某一層,另一層也要跟著改動,是不是很難受?

所以我們目前要解決:(如果每次 dao 進行擴展都去 service 修改源碼來切換到新的 dao,這樣做法耦合度太高,每次都需要去修改 UserServiceImpl 的代碼)

這個場景,我們很經典的稱為耦合!!!!我們可以自己給耦合多一個定義

耦合: 代碼之間的關聯關系稱為耦合,更具體的說,在當前主流的職責劃分層次(controller,service,dao)明確的前提下進行編碼,某一層的改動,會導致另一個層跟著變動,可以稱為耦合。

3、工廠模式可以解耦

在不了解工廠模式的前提下,就默認把這個作為生產對象的地方;

我們新建一個工廠,稱為 BeanFactory

/**

* 定義一個 bean 工廠,專門生產普通對象

*/

publicclassBeanFactory{

publicstaticUserDaogetBean() {

returnnewUserDaoMysqlImpl();

}

}

然后我們要對耦合的那一層修改,目前看是把 service 解耦了吧?我所有創建對象的操作,都在一個具體的工廠類里;

publicclassUserServiceImplimplementsUserService{

// 業務層調用數據 dao 層,這里不解釋了

// private UserDao userDao = new UserDaoMysqlImpl();

// private UserDao userDao = new UserDaoOracleImpl();

privateUserDao userDao = BeanFactory.getBean();

@Override

publicvoidsave() {

userDao.save();

}

}

很明顯,我已經進行了 service 和 dao 解耦;但是!!!!!!

該死的需求是:我要改成 oracle,sqlserver,……

那我們繼續:我順便把之前的 getBean 換成了 mysql 的

publicclassUserServiceImplimplementsUserService{

// 業務層調用數據 dao 層,這里不解釋了

// private UserDao userDao = new UserDaoMysqlImpl();

// private UserDao userDao = new UserDaoOracleImpl();

// private UserDao userDao = BeanFactory.getMysqlBean();

privateUserDao userDao = BeanFactory.getOracleBean();

@Override

publicvoidsave() {

userDao.save();

}

}

很明顯我現在已經把 dao 和 service 的耦合,轉移到了工廠和 service 上了,這就是解耦的一步;但是大家還是疑惑,我感覺我代碼增多了?或者更麻煩了?我們繼續看

我們每次增加新的業務,擴展,都要修改工廠,所以這個我們可以不可以不在代碼里直接做這個事情?——– 引出配置文件

我們在 resources 下定義一個 applicationContext.properties

userDao=com.chenxin.gmall.user.demo.dao.UserDaoMysqlImpl

userService=com.chenxin.gmall.user.demo.service.UserServiceImpl

如果我們需要換成 oracle,我們只改這個配置文件,改成 UserDaoOracleImpl,不需要去動代碼

那我們剛剛的 BeanFactory 就又可以通過讀取配置文件的方式,用反射來創建對象,反射創建對象是根據對象的全類名做的,不是直接 new,看看效果

/**

* 定義一個 bean 工廠,專門生產普通對象

*/

publicclassBeanFactory{

privatestaticProperties properties =newProperties();

//1. 加載配置文件

static{

InputStream resourceAsStream = BeanFactory.class.getResourceAsStream(“/applicationContext.properties”);

try{

properties.load(resourceAsStream);

resourceAsStream.close();

}catch(IOException e) {

e.printStackTrace();

}

}

//publicstaticUserDaogetMysqlBean() {

// return new UserDaoMysqlImpl();

// }

//

// public static UserDao getOracleBean() {

// return new UserDaoOracleImpl();

// }

publicstaticUserDaogetBean(String key){

// 2. 使用 key 獲得 value

String className = properties.getProperty(key);

// 3. 使用 value 利用反射技術創建對象

try{

return(UserDao) Class.forName(className).newInstance();

}catch(Exception e){

e.printStackTrace();

returnnull;

}

}

}

好了,我們來需求,我們要保存到 oracle,sqlserver 數據庫,看看你是不是只需要多一個 dao 的 oracle 實現,然后去改配置文件就 ok?多一個 sqlserver 后,改下 applicationContext.properties

算了我直接寫個代碼吧:

/**

* 新增了 sqlserver 的支持,多態的表現

*/

publicclassUserDaoSqlServerImplimplementsUserDao{

@Override

publicvoidsave() {

System.out.println(“ 保存 SqlServer 數據庫成功!”);

}

}

改下 applicationContext.properties

userDao=com.chenxin.gmall.user.demo.dao.UserDaoSqlServerImpl

userService=com.chenxin.gmall.user.demo.service.UserServiceImpl

你可以試一下,是不是這么干的!

現在看來,是解耦了不少吧。但是會有人發現嗎,這個 getBean 返回值,是 UserDao,如果你有很多,是不是我們要寫很多很多的 Dao 的 getBean?別急,后面一步一步帶你走向 spring 的思路

最后一句話,解耦不代表代碼一定少,更多時候是你用更多的代碼來解決人力成本,所以新手一定要記得,解耦的原則,是減少開發中出現的問題,增加開發效率,不代表代碼一定會減少下去,希望不要有這樣的誤區!

感謝閱讀,三連是最大的支持!

丸趣 TV 網 – 提供最優質的資源集合!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2024-04-10發表,共計4316字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 沧源| 侯马市| 仙桃市| 永泰县| 手游| 黑山县| 井冈山市| 仁布县| 南木林县| 新津县| 信丰县| 沈丘县| 射阳县| 怀远县| 铜梁县| 岳普湖县| 伊春市| 仁怀市| 枝江市| 扎囊县| 庆元县| 尼木县| 班玛县| 衡南县| 鄂尔多斯市| 张掖市| 九江县| 揭西县| 四平市| 定陶县| 筠连县| 巴南区| 玉门市| 封开县| 四会市| 庄河市| 常德市| 和龙市| 贞丰县| 肇东市| 昌都县|