欧美日产国产成人免费图片,国产精品久久久久av蜜臀,欧美韩国日本一区,在线精品亚洲一区二区不卡

解耦解釋(解耦是什么)

華峰博客 208

推薦學習:

這可能是全網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的思路

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

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

上一篇:

下一篇:

? 同類閱讀

分享
? ?
? ?
主站蜘蛛池模板: 辰溪县| 屏边| 灵寿县| 乌拉特前旗| 宁乡县| 汾阳市| 肥西县| 泉州市| 乐安县| 会东县| 民乐县| 瑞丽市| 湘潭市| 威信县| 汉川市| 栾城县| 泸州市| 镶黄旗| 荣昌县| 宁晋县| 新津县| 宝兴县| 鄂托克旗| 汤阴县| 壤塘县| 永登县| 临猗县| 项城市| 惠州市| 水城县| 拉萨市| 榕江县| 汉川市| 绥滨县| 宁波市| 临漳县| 连平县| 大埔区| 申扎县| 锡林郭勒盟| 荥经县|