框架前奏
框架前奏
穿插之前的JAVAWEB項(xiàng)目,之后的Spring框架。
JAVAWEB項(xiàng)目:用到技術(shù)點(diǎn)
-
MVC模式
-
數(shù)據(jù)庫連接技術(shù)(JDBC)
-
分層思想
1.先創(chuàng)建JAVAWEB項(xiàng)目(IDEA)
? 使用tomcat,配置運(yùn)行一下
2.src下的目錄
某新聞系統(tǒng),主題為例,Topic
搭建框架
-
? com.aaa.dao:數(shù)據(jù)訪問層的包
-
com.aaa.dao.impl:數(shù)據(jù)訪問層接口的實(shí)現(xiàn)類
-
com.aaa.service:業(yè)務(wù)層的包,主要放業(yè)務(wù)層接口
-
com.aaa.service.impl:業(yè)務(wù)層包的實(shí)現(xiàn)類:主要放業(yè)務(wù)層接口實(shí)現(xiàn)類
-
com.aaa.controller:Servlet,去調(diào)用業(yè)務(wù)層的接口及其實(shí)現(xiàn)類。
controller是之前的寫法,今天的測(cè)試,換成了一個(gè)test包,在test包下建立一個(gè)test類,來測(cè)試業(yè)務(wù)層接口及其實(shí)現(xiàn)類。
這個(gè)其實(shí)和使用servlet測(cè)試是一樣。
? 剛才我們講了,搭建。在控制臺(tái)做了測(cè)試輸出。
3.setter解耦
數(shù)據(jù)庫mysql,oracle
有mysql的數(shù)據(jù)訪問層的實(shí)現(xiàn),有oracle的數(shù)據(jù)訪問層的實(shí)現(xiàn)。
業(yè)務(wù)層,這里實(shí)現(xiàn)的是TopicDaoMysqlImpl,針對(duì)的mysql數(shù)據(jù)庫的操作。
我們現(xiàn)在的操作都變了,要去操作oracle數(shù)據(jù)庫。怎么辦呢???
TopicDao topicDao=new TopicDaoMysqlImpl();代碼改變:
TopicDao topicDao=new TopicDaoOracleImpl();運(yùn)行之后,可以看到,會(huì)改變?yōu)閯h除oracle數(shù)據(jù)庫中的主題編號(hào):
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-GKiyCtrG-1591145306194)(E:\政通路\課堂筆記\S2\Spring\assets\image-20200601163742411.png)]y
大家要總結(jié)一下,當(dāng)我們的數(shù)據(jù)庫變更的時(shí)候,這樣操作的方式好不好呢???
? 假如說,我們的項(xiàng)目已經(jīng)部署上線了,項(xiàng)目在運(yùn)行,你來改變代碼來了。不能說肯定會(huì)出現(xiàn)問題,但是出現(xiàn)問題的幾率一定是比較大。
? 能不能有一種方式,由客戶自己來決定變更使用哪種數(shù)據(jù)庫或者是客戶自己決定某種操作。
這種問題,其實(shí)就是程序的耦合問題。
之前學(xué)習(xí)過OOP,三大特征:封裝、繼承、多態(tài)。
要實(shí)現(xiàn)的目標(biāo)是:高內(nèi)聚、低耦合、高復(fù)用
我們?cè)趯懗绦虻臅r(shí)候,盡量低耦合。不new具體的對(duì)象;
重點(diǎn)代碼:
package com.aaa.service.impl;import com.aaa.dao.TopicDao; import com.aaa.dao.impl.TopicDaoMysqlImpl; import com.aaa.dao.impl.TopicDaoOracleImpl; import com.aaa.service.TopicService; /*** Created by 張晨光 on 2020/6/1 16:19* 主題業(yè)務(wù)層的實(shí)現(xiàn)類;java程序員 調(diào)用dao層,不改.* 調(diào)用dao層的接口及其實(shí)現(xiàn);*/ public class TopicServiceImpl implements TopicService {//定義dao層對(duì)象,及其實(shí)現(xiàn)類;//TopicDao topicDao=new TopicDaoMysqlImpl();//TopicDao topicDao=new TopicDaoOracleImpl();//這種方式:是通過new 出來dao層對(duì)象的具體的實(shí)現(xiàn)類。//能不能有一種方式,交由客戶自己來調(diào)用的時(shí)候來實(shí)現(xiàn)呢???//盡量少的動(dòng)代碼;//這種其實(shí)就是程序之間的耦合問題。//********************松耦合的實(shí)現(xiàn)************TopicDao topicDao;//創(chuàng)建它的getter/setterpublic TopicDao getTopicDao() {return topicDao;}//重點(diǎn)看這個(gè):參數(shù)是一個(gè)TopicDao的對(duì)象;public void setTopicDao(TopicDao topicDao) {this.topicDao = topicDao;}@Overridepublic void deleteTopicById(Integer id) {//在方法里面,通過dao層對(duì)象去執(zhí)行刪除操作;//注意看:這里面有topicDao的對(duì)象的new ???沒有了topicDao.deleteTopicById(id);} }客戶端的使用:
TopicService topicService=new TopicServiceImpl();//在業(yè)務(wù)層實(shí)現(xiàn)類代碼里面,已經(jīng)沒有了new TopicDaoOracleImpl的代碼,我們的目標(biāo)就是去掉這個(gè)//代碼,實(shí)現(xiàn)松耦合//通過setter來實(shí)現(xiàn)//((TopicServiceImpl) topicService).setTopicDao(new TopicDaoOracleImpl());//客戶變更為了mysql((TopicServiceImpl) topicService).setTopicDao(new TopicDaoMysqlImpl());//由原來在業(yè)務(wù)層實(shí)現(xiàn)類的具體的new xxxImpl,交由客戶端test類自動(dòng)選擇,我要new。//topicService.deleteTopicById(3);//模擬實(shí)現(xiàn);總結(jié):
-
耦合度:模塊間的耦合度是指模塊之間的依賴關(guān)系;java里面的耦合度指的是類、接口、實(shí)現(xiàn)之間的關(guān)聯(lián)程度。
-
解耦:通過把創(chuàng)建接口對(duì)象的setter()方法,在客戶端由客戶決定哪種數(shù)據(jù)庫的使用。
-
高內(nèi)聚:盡可能類的每個(gè)成員方法只完成一件事(最大限度的聚合)
-
之前的數(shù)據(jù)庫連接代碼,放在了BaseDao里面,是寫死的,需要修改也得改代碼。可以放在db.properties配置文件,也是解耦的一種表現(xiàn)。
作業(yè):
- ? 使用UserDao來解耦之前JAVAWEB代碼,模仿TopicDao。
—************
首先是熟練操作IDEA,創(chuàng)建WEB項(xiàng)目,使用tomcat,配置、部署運(yùn)行等。
復(fù)習(xí):
面向?qū)ο蟮哪繕?biāo):高內(nèi)聚、低耦合、高復(fù)用
原來JAVAWEB項(xiàng)目存在高耦合的情況,我們要解耦,我們使用的接口對(duì)象的setter()方法進(jìn)行解耦操作。
4.解耦方式二
程序的耦合
? 耦合:程序間的依賴關(guān)系,包括:
? a.類之間的關(guān)系
? b.方法間的關(guān)系
? 解耦:降低程序間的依賴關(guān)系
為bug生,為bug死,為bug奮斗終生
為解耦生,為解耦死,為解耦?yuàn)^斗終生–》只要項(xiàng)目你不斷完善,就存在類、方發(fā)、模塊、項(xiàng)目之間的耦合度。
? 實(shí)際開發(fā)中:
? 應(yīng)該做到,編譯時(shí)不依賴,運(yùn)行時(shí)依賴
? 解耦的思路:
? 第一步:使用反射來創(chuàng)建對(duì)象,而避免使用new關(guān)鍵字。Class.forName("")
? 第二步:通過讀取配置文件來獲取要?jiǎng)?chuàng)建的對(duì)象全限定類名。xxx.properties/xxx.xml文件
使用xml文件的解耦,這個(gè)將來和spring框架會(huì)聯(lián)系起來,將我們的技術(shù)串起來。以聽為主,不用記憶。
1.在src下建立beans.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans><!--beans:指的所有bean的集合,使用xml文件進(jìn)行解耦--><!--bean:單個(gè)bean的配置文件;id:bean的編號(hào);class:bean路徑--><!--class:mysql下數(shù)據(jù)庫的實(shí)現(xiàn)類;給這個(gè)類起id名topicDaoMysqlImpl--><bean id="topicDaoMysqlImpl" class="com.aaa.dao.impl.TopicDaoMysqlImpl"></bean><!--topicServiceImpl解耦--><bean id="topicServiceImpl" class="com.aaa.service.impl.TopicServiceImpl"></bean> </beans>bean:咖啡豆;在java 組件
JAVABEAN:指的就是JAVA里面的可重用組件,玩具:可以由若干零部件組成,組件(組成的零件),在JAVA里面,業(yè)務(wù)層的接口、接口的實(shí)現(xiàn)類、dao層接口、dao層接口的實(shí)現(xiàn)類,可以被多次調(diào)用(被重用),這些被重用的類、接口都是JAVABEAN。
JAVABEAN的范圍遠(yuǎn)大于實(shí)體類,實(shí)體類僅僅指的是業(yè)務(wù)傳遞數(shù)據(jù)時(shí)的一種重用形態(tài)。
2.建立BeanFactory類,操作xml文件
2.1 jar包準(zhǔn)備
IDEA的web-INF創(chuàng)建,lib目錄,然后把xml的jar放進(jìn)去,然后Add as Library
2.2 使用BeanFactory來獲取bean
package com.aaa.util;import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;/*** Created by 張晨光 on 2020/6/2 15:01* Bean:重用組件;--》JAVABEAN;* Factory:工廠的意思;BeanFactory:Bean的工廠;* 顧名思義:批量創(chuàng)建Bean;操作beans.xml文件,創(chuàng)建bean*/ public class BeanFactory {//定義靜態(tài)方法根據(jù)id來獲取Bean對(duì)象;public static Object getBean(String id){//用類加載器解析xml文件try {SAXReader reader = new SAXReader(); //xml的reader對(duì)象//getClassLoader():類加載器,getResourceAsStream:將資源加載為流;Document document = reader.read(BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"));//xpath技術(shù)獲得bean元素;相當(dāng)于之前js:document.getElementById("id")Element element = (Element) document.selectSingleNode("//bean[@id='"+id+"']");//拿到class屬性里面的值String value = element.attributeValue("class");//獲得反射對(duì)象System.out.println(value);//通過類的全限定名加載類對(duì)象[包名+類名];得到value類的class(TopicDaoMysqlImpl):它的類信息;//是不是可以想到:Class.forName("com.mysql.cj.jdbc.Driver")Class clazz = Class.forName(value);//獲得實(shí)例return clazz.newInstance();} catch (Exception e) {e.printStackTrace();throw new RuntimeException();}} }3.測(cè)試類
//2.1通過BeanFactory來獲取一下;TopicService topicService = (TopicService) BeanFactory.getBean("topicService");//2.直接調(diào)用即可topicService.deleteTopicById(2);總結(jié):
1.通過建立配置文件xml解耦
`
3.測(cè)試類
//2.1通過BeanFactory來獲取一下;TopicService topicService = (TopicService) BeanFactory.getBean("topicService");//2.直接調(diào)用即可topicService.deleteTopicById(2);總結(jié):
1.通過建立配置文件xml解耦
2.建立BeanFactory解析xml文件,使用反射機(jī)制來讀取類信息,創(chuàng)建類實(shí)例,實(shí)現(xiàn)自動(dòng)創(chuàng)建對(duì)象的操作。
總結(jié)
- 上一篇: 记录一个解决了一个下午加一个晚上的问题,
- 下一篇: 框架前奏二