版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、軟件設(shè)計模式第2章面向?qū)ο蟪绦蛟O(shè)計原則提綱2.1 單一職責(zé)原則(SRP)2.2 “開/閉”原則(OCP)2.3 接口隔離原則(ISP)2.4 依賴倒置原則(DIP)2.5 Liskov替換原則(LSP)2.1 單一職責(zé)原則(SRP)單一職責(zé)面向?qū)ο笤O(shè)計原則強(qiáng)調(diào):一個類或模塊應(yīng)僅有一個引起其變化的因素(職責(zé))。通俗地講,一個類或模塊應(yīng)只承擔(dān)一個(或一種類型的)業(yè)務(wù)職責(zé)當(dāng)類承擔(dān)的業(yè)務(wù)職責(zé)較多時,該類中任何職責(zé)需求的變化都會引起靜態(tài)實(shí)現(xiàn)的變化,和導(dǎo)致其代碼不穩(wěn)定無論是向目標(biāo)類添加新的代碼,或修改已有的代碼,都是對原有代碼設(shè)計的破壞,導(dǎo)致程序開發(fā)者花費(fèi)巨大成本進(jìn)行代碼修復(fù)圖2.1 多個業(yè)務(wù)行為的Pat
2、ron類例如,COS系統(tǒng)中客戶角色具有的業(yè)務(wù)行為有:登錄系統(tǒng),支付訂單,查看菜單等,如圖2.1。如果將所有的業(yè)務(wù)行為實(shí)現(xiàn)在客戶類Patron中,當(dāng)這些業(yè)務(wù)行為中的任何一個需求發(fā)生變化時,如支付或登錄行為需求發(fā)生變化,都需要修改Patron類。即,影響Patron類變化的因素多于1個時,會導(dǎo)致Patron類的代碼變得不穩(wěn)定。圖2.1中Patron類的代碼框架:圖2.2 遵守“單一職責(zé)”原則設(shè)計的Patron類按照單一職責(zé)原則設(shè)計Patron類時,可以將登錄系統(tǒng)、支付訂單等業(yè)務(wù)職責(zé)分別單獨(dú)地封裝在其他類中,從而減少Patron類的業(yè)務(wù)職責(zé)。如圖2.2,將登錄行為封裝在Employee中,支付訂單行
3、為封裝在PayOrder中。 此時,Patron繼承Employee和依賴PayOrder,其類的代碼框架如下:符合“單一職責(zé)”設(shè)計原則的圖2.2的設(shè)計方案減少了影響Patron變化的因素,使其代碼更加穩(wěn)定。工程師在使用“單一職責(zé)”原則設(shè)計類時,也會產(chǎn)生如下問題:1)設(shè)計類數(shù)量的增加。如果一個龐大業(yè)務(wù)系統(tǒng)的所有類按單一職責(zé)設(shè)計,則有可能導(dǎo)致設(shè)計類數(shù)量的“爆炸(Explosion)”。此外,設(shè)計類數(shù)量的增加也會使設(shè)計方案復(fù)雜度增大。2)類封裝特性的破壞。由于數(shù)據(jù)域封裝在目標(biāo)(實(shí)體)類中,如果從目標(biāo)類中將含有數(shù)據(jù)域訪問邏輯的業(yè)務(wù)行為分離出去,則勢必造成外部代碼訪問目標(biāo)類私有域的問題,而最終破壞目標(biāo)
4、類的封裝特性。3)其他問題。完全教條式地運(yùn)用“單一職責(zé)”設(shè)計類時,也可能會降低代碼的內(nèi)聚或增加代碼的耦合。同時,類職責(zé)沒有明確的定義,可以是具體業(yè)務(wù)功能或行為,也可以是抽象邏輯;因此,其邊界是模糊的,難以清晰地劃定單一職責(zé)。2.1 “開/閉”原則(OCP) “開/閉”原則要求:類或模塊的代碼“對擴(kuò)展是開放的”(Open for Extension)、“對修改是關(guān)閉的”(Close for Modification)。當(dāng)軟件需求發(fā)生變化時,目標(biāo)類或模塊的代碼可以通過代碼擴(kuò)展,很容易地實(shí)現(xiàn)新的需求;而不是修改已有類或模塊的代碼。因?yàn)椋浖a業(yè)務(wù)邏輯充滿了耦合,當(dāng)一處代碼修改時,將會引發(fā)已有代碼邏
5、輯變化,產(chǎn)生邏輯錯誤或制造出新的代碼缺陷。圖2.3 PayOrder類可擴(kuò)展性設(shè)計 COS系統(tǒng)需求提到的訂單支付方式是工資抵扣或現(xiàn)金;在圖2.2中,支付訂單行為的實(shí)現(xiàn)封裝在PayOrder類中。如果只考慮這兩種支付行為,工程師一般會在PayOrder類中使用分支結(jié)構(gòu)直接實(shí)現(xiàn)支付業(yè)務(wù)邏輯。這種代碼結(jié)構(gòu)存在的問題有:1)如果COS支付需求發(fā)生變化,則必須修改PayOrder已有的分支結(jié)構(gòu)才能滿足新需求;2)由于Patron依賴于PayOrder,則PayOrder代碼的變化會直接影響到依賴者Patron。要解決上面的問題,需要重新設(shè)計PayOrder類結(jié)構(gòu),具體方案見圖2.3。 在圖2.3中,將P
6、ayOrder泛化為一個接口或抽象類,其定義抽象的支付行為check();現(xiàn)金支付訂單方式的業(yè)務(wù)邏輯由子類PayByCash實(shí)現(xiàn),工資抵扣支付訂單方式的業(yè)務(wù)邏輯由子類PayByPRDS實(shí)現(xiàn)。代碼示例如下。PayOrder類結(jié)構(gòu):PayByCash類結(jié)構(gòu):PayByPRDS類結(jié)構(gòu): 那么,在圖2.3的類設(shè)計方案中,當(dāng)支付行為需求發(fā)生變化時,可以定義PayOrder新的子類實(shí)現(xiàn)新需求,而不需要修改已有的類(或接口)PayOrder、PayByCash、PayByPRDS等。 例如,COS系統(tǒng)升級時,新需求要添加電子銀行支付訂單方式。那么,工程師可以直接定義PayOrder的子類PayByEBank
7、來實(shí)現(xiàn)該需求,如圖2.4。圖2.4 添加電子銀行支付后的PayOrder類結(jié)構(gòu)設(shè)計 在圖2.4中,PayByEBank子類的添加并不會影響PayByCash、PayByPRDS等已有的類(或接口),且實(shí)現(xiàn)了新支付方式的擴(kuò)展。PayByBank類結(jié)構(gòu):那么,PayByEBank類的添加對Patron(客戶)類是否會產(chǎn)生影響? 這種依賴關(guān)系不受具體實(shí)現(xiàn)類型的影響。因此,PayByEBank類的添加也沒有影響到客戶類Patron。 從可擴(kuò)展性和代碼穩(wěn)定性角度看,圖2.3中PayOrder類的設(shè)計方案要優(yōu)于圖2.2,符合“開/閉”原則的設(shè)計思想。 實(shí)施“開/閉”原則設(shè)計代碼時,工程師可以使用抽象、繼承
8、、組合等面向?qū)ο蠹夹g(shù)獲得代碼靈活性、可重用性、可擴(kuò)展性等方面的好處。但也應(yīng)看到,“開/閉”原則對代碼還有以下的影響:1)代碼可讀性降低。由于使用了抽象,代碼設(shè)計邏輯與業(yè)務(wù)需求邏輯相比,會產(chǎn)生變化,抽象代碼層隱藏了具體業(yè)務(wù)細(xì)節(jié),大大降低了源碼的可讀性。2)程序測試成本增加。同樣地,使用抽象設(shè)計會使測試人員無法靜態(tài)確定具體對象的引用類型,必須等到程序運(yùn)行時才能確定目標(biāo)對象的具體類型。因此,代碼缺陷可能會滯后到程序運(yùn)行后才被發(fā)現(xiàn);又或者,程序出現(xiàn)錯誤后,只有通過動態(tài)調(diào)試的方法才能有效地定位缺陷。最終,它們都會導(dǎo)致測試成本的增加。2.3 接口隔離原則(ISP)接口隔離原則指出:如果某個接口的行為不是內(nèi)
9、聚的,就應(yīng)該按照業(yè)務(wù)分組,并將分組后的業(yè)務(wù)行為通過隔離的接口單獨(dú)定義。接口的行為要向調(diào)用它的客戶端提供業(yè)務(wù)服務(wù);對于不同的業(yè)務(wù)分組,調(diào)用它的客戶端是相互獨(dú)立的;因此,接口提供的服務(wù)(分組)也應(yīng)該是相互獨(dú)立的。圖2.5 打印配送單和發(fā)送配送指令行為定義在IDeliver接口中 例如,在COS系統(tǒng)需求中,餐廳員工(Cafeteria Staff)和配餐員(Meal Deliverer)都有打印配送單(Print Delivery Instructions)的行為;而且,餐廳員工還有發(fā)送配送指令(Issue Delivery Request)的行為。如果將打印配送單行為和發(fā)送配送指令行為強(qiáng)行定義在接
10、口IDeliver中,如圖2.5,將會產(chǎn)生如下問題:1)子類(或?qū)崿F(xiàn)類)可能會繼承(或?qū)崿F(xiàn))冗余行為。配餐員MealDeliverer作為IDeliver的實(shí)現(xiàn)類,需要實(shí)現(xiàn)issueDeliveryQuest()方法;然而,在COS的需求中,配餐員不具有該行為。2)子類(或?qū)崿F(xiàn)類)的客戶端受到不相干的業(yè)務(wù)行為干擾。假設(shè)餐廳員工CafeteriaStaff想要改變issueDeliveryQuest()的行為定義,比如修改方法名稱;那么,則要修改接口IDeliver。而IDeliver接口的變化會導(dǎo)致實(shí)現(xiàn)類MealDeliverer變化,最終影響到調(diào)用MealDeliverer的所有客戶端。要解
11、決上面的問題,工程師可以按照接口隔離原則提供的建議將接口中的方法進(jìn)行業(yè)務(wù)分組。由于打印打印配送單和發(fā)送配送指令是不同的業(yè)務(wù)行為,兩者之間的內(nèi)聚度很弱,分離它們可以降低相互影響。圖2.6 使用“接口隔離”原則設(shè)計打印配送單和發(fā)送配送指令行為 因此,將圖2.5中的IDeliver接口行為printDeliveryInstruction()和issueDeliveryQuest()分別定義在的接口IPrintDelivery和IIssueDelivery中,用于實(shí)現(xiàn)行為的隔離;如圖2.6所示。 IIssueDelivery接口定義了issueDeliveryQuest()行為,IPrintDeliv
12、ery接口定義了printDeliveryInstruction()行為,彼此獨(dú)立,互不影響。CafeteriaStaff類實(shí)現(xiàn)IIssueDelivery、IPrintDelivery接口,MealDeliverer實(shí)現(xiàn)IPrintDelivery接口。 可以看到,MealDeliverer只實(shí)現(xiàn)了自身需要的業(yè)務(wù)行為printDeliveryInstruction(),不用實(shí)現(xiàn)冗余行為issueDeliveryQuest(),保證了代碼邏輯與需求的一致性。此外,IIssueDelivery接口定義的變化只對其實(shí)現(xiàn)類CafeteriaStaff產(chǎn)生影響,而不會對MealDeliverer造成任
13、何影響。圖2.6中類圖代碼框架如下。IIssueDelivery接口:IPrintDelivery接口: 在Java編程語言中,IPrintDelivery接口可以定義printDeliveryInstruction()行為的默認(rèn)實(shí)現(xiàn),CafeteriaStaff、MealDeliverer根據(jù)需求選擇重寫或使用接口默認(rèn)。以CafeteriaStaff為例,代碼結(jié)構(gòu)如下。CafeteriaStaff實(shí)現(xiàn)類: 按照接口隔離原則設(shè)計的代碼能夠避免“接口污染”(指接口的實(shí)現(xiàn)類實(shí)現(xiàn)了冗余方法,使得代碼質(zhì)量下降),對軟件維護(hù)或代碼重構(gòu)提供很好地支持。在使用接口隔離原則設(shè)計代碼時,工程師需要注意以下問題:
14、1)接口數(shù)量“爆炸”。按照“接口隔離”原則對目標(biāo)系統(tǒng)的業(yè)務(wù)行為分組,將會產(chǎn)生巨大數(shù)量的細(xì)粒度接口定義;如同類“爆炸”概念一樣,當(dāng)接口過多時,也會導(dǎo)致軟件開發(fā)或維護(hù)成本的急劇上升。2)代碼抽象度高。抽象度高的代碼具有穩(wěn)定性、可復(fù)用性等優(yōu)點(diǎn),面向抽象編程較為推崇這種代碼設(shè)計思維。但,也應(yīng)指出:代碼抽象度越高,代碼實(shí)現(xiàn)越復(fù)雜;代碼抽象度越高,代碼可讀性(或可理解度)越差!2.4依賴倒置原則(DIP)依賴倒置面向?qū)ο笤O(shè)計原則建議:1)高層模塊不應(yīng)依賴于低層模塊,二者都應(yīng)該依賴于抽象;2)抽象不應(yīng)依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)依賴于抽象。 在分層的軟件架構(gòu)中,業(yè)務(wù)邏輯實(shí)現(xiàn)的模塊被稱為高層模塊,數(shù)據(jù)或服務(wù)支持模塊是底
15、層模塊,如圖2.7圖2.7 高層模塊與低層模塊的依賴關(guān)系 圖2.7中,業(yè)務(wù)層依賴于數(shù)據(jù)或服務(wù)層;即,高層模塊依賴低層模塊。當(dāng)?shù)蛯幽K發(fā)生變化時,高層模塊則不可避免地受到影響。特別地,當(dāng)目標(biāo)系統(tǒng)分層較多時,最低層模塊代碼的變化,會影響到所有的(含有直接依賴或間接依賴)高層模塊。 為了減少依賴或依賴傳遞對高層模塊的影響,要使高層模塊依賴于穩(wěn)定的抽象。那么,將低層模塊向高層模塊提供服務(wù)定義為抽象,高層模塊依賴于抽象;抽象是穩(wěn)定的,抽象具體實(shí)現(xiàn)的變化不會影響到高層模塊,如圖2.8。圖2.8 按照“依賴倒置”原則設(shè)計模塊依賴關(guān)系示意 相較于圖2.7中的高層模塊直接依賴于低層模塊實(shí)現(xiàn),圖2.8中的高層模塊
16、依賴于底層模塊的抽象;低層模塊實(shí)現(xiàn)也同時依賴于抽象的定義(接口實(shí)現(xiàn)或類繼承是一種強(qiáng)約束依賴關(guān)系,實(shí)現(xiàn)類或子類均依賴接口或父類的方法定義)。當(dāng)?shù)蛯訉?shí)現(xiàn)變化時,由于低層模塊的抽象隔離了變化,高層模塊感知不到這種變化,也就不會受到該變化的影響。 舉個例子:在COS系統(tǒng)中,客戶(Patron)支付訂單的業(yè)務(wù)依賴于支付類(PayOrder);如果PayOrder是支付服務(wù)的實(shí)現(xiàn)類,則形成了高層代碼Patron直接依賴于低層實(shí)現(xiàn)PayOrder的邏輯關(guān)系,如圖2.9。圖2.9 Patron直接依賴于PayOrder實(shí)現(xiàn) 由于PayOrder是支付服務(wù)的實(shí)現(xiàn),當(dāng)支付服務(wù)需求發(fā)生變化時,則需要修改PayOrd
17、er已有代碼,或重新定義實(shí)現(xiàn)新需求的子類。無論哪種方式,客戶端Patron都會感知到支付服務(wù)的變化,并受到影響。假設(shè),圖2.9中的PayOrder類的check()方法實(shí)現(xiàn)了工資抵扣支付訂單行為。那么,要實(shí)現(xiàn)電子銀行支付訂單行為的新需求,則解決方案會是以下兩種中的一個:1)修改PayOrder類,添加電子銀行支付訂單服務(wù)行為;修改客戶端Patron支付邏輯,使得Patron可以使用PayOrder新添加的電子銀行支付行為;2)繼承PayOrder,添加電子銀行支付訂單行為子類;修改Patron支付邏輯,使得Patron可以依賴新添加的電子銀行支付行為子類。以上兩種解決方案都無法避免對客戶端Pa
18、tron代碼的修改。即,低層模塊實(shí)現(xiàn)的變化直接影響了高層模塊。 按照“依賴倒置”原則的建議重新設(shè)計Patron與PayOrder之間的依賴關(guān)系,將低層模塊提供的服務(wù)進(jìn)行抽象,封裝為抽象類或接口;使高層模塊依賴于低層模塊的抽象類(或接口);低層模塊的實(shí)現(xiàn)類繼承(或?qū)崿F(xiàn))抽象類(或接口);如圖2.10所示。圖2.10按照“依賴倒置”原則重新設(shè)計Patron與PayOrder之間的依賴關(guān)系圖2.10的類圖結(jié)構(gòu)與圖2.3、圖2.4的類圖結(jié)構(gòu)一致,示例代碼可參見2.2節(jié)。 由于將圖2.10中的PayOrder設(shè)計為抽象類(或接口),Patron對PayOrder的依賴關(guān)系就變得穩(wěn)定了。子類PayByPR
19、DS實(shí)現(xiàn)了工資抵扣支付訂單服務(wù),PayByEBank實(shí)現(xiàn)了電子銀行支付訂單服務(wù);實(shí)現(xiàn)類的變化不會影響到客戶端Patron。因此,圖2.10的設(shè)計類圖不僅能保證代碼穩(wěn)定性,也具有良好的可擴(kuò)展性。“依賴倒置”原則提供的代碼設(shè)計建議可以很好地實(shí)現(xiàn)代碼解耦。“依賴倒置”原則所體現(xiàn)的設(shè)計思維,在不同材料中有不同的名稱,如“好萊塢”原則(Hollywood Principle)、回調(diào)機(jī)制(Callback Mechnism)等。 在使用依賴倒置原則時,工程師需要注意以下問題:1)增加了代碼復(fù)雜度。依賴倒置的設(shè)計方式無疑會增加接口或抽象類的數(shù)量,使得軟件代碼結(jié)構(gòu)變得抽象或復(fù)雜。2)更適合應(yīng)對需求變化。由于將
20、依賴關(guān)系指向抽象,抽象能夠隔離調(diào)用者與被調(diào)用者的實(shí)現(xiàn),使得二者的變化不會相互影響,在一定程度上保證了代碼穩(wěn)定性。依賴倒置的代碼能夠通過穩(wěn)定的依賴關(guān)系將新需求加入,或?qū)⒃枨笞兓鶐淼挠绊懡档停灰虼?,其更適合應(yīng)對有需求變化的代碼設(shè)計。2.5 Liskov替換原則(LSP)對于靜態(tài)類型的面對象編程語言,如Java、C#,繼承是多態(tài)技術(shù)實(shí)現(xiàn)的主要方式。通過繼承,子類可以重寫父類定義的方法,使得父類(或接口)定義的對象引用可以指向不同的子類實(shí)例,形成同一個行為的調(diào)用表現(xiàn)出多態(tài)特征。Liskov替換原則(有的資料翻譯成“里氏”替換原則)建議:子類型對象必須能夠完全替換掉它們的父類型對象,而不需要改變父
21、類型的任何屬性。Liskov替換原則是美國計算機(jī)科學(xué)家Barbara Liskov(女,曾于2008年獲得圖靈獎)于1987年在期刊ACM SIGPLAN Notices發(fā)表的標(biāo)題為“Data Abstraction and Hierarchy”的文章中所提出的形式化原則。其原文中的表述為:對于類型S的對象o1,存在類型T的對象o2,如果能使T編寫的程序P的行為在o1替換o2后保持不變,則S是T的子類型(If for each object o1 of type S there is an object o2 of type T such that for all programs P def
22、ined in terms of T,the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T)。 Liskov替換原則提出了如何規(guī)范地使用繼承。一旦違反該規(guī)則,則有可能會導(dǎo)致程序表達(dá)錯誤。例如,在COS系統(tǒng)中,工程師需要實(shí)現(xiàn)統(tǒng)計圖表的繪制功能,圖表組件類型有:柱狀圖(Bar)、線狀圖(Line)等。工程師設(shè)計了圖表組件父類ChartComponent,并定義組件繪制行為draw();子類Bar繼承ChartComponent和實(shí)現(xiàn)繪制柱狀圖行為,Line繼承ChartCompo
23、nent和實(shí)現(xiàn)繪制線狀圖行為;柱狀圖Bar額外定義了方法fill(),用于圖形填充行為的實(shí)現(xiàn);使用組件對象進(jìn)行圖表繪制的客戶類是ChartDrawer;如圖2.11。圖2.11 COS圖表繪制類結(jié)構(gòu) 由于不同的圖表組件繪制方式不同;如,繪制柱狀圖不僅繪制柱形,還需對圖形進(jìn)行填充,而繪制線狀圖則不需要填充;ChartDrawer代碼結(jié)構(gòu)可以是:ChartComponent抽象類代碼結(jié)構(gòu)如下: Bar和Line作為ChartComponent的子類,分別實(shí)現(xiàn)柱狀圖、線狀圖繪制,以Bar為例,其代碼結(jié)構(gòu)如下: 從上面的代碼中可以看到,ChartDrawer在繪制不同類型圖表組件時,需要知道組件的子類
24、型,然后才能對該組件進(jìn)行繪制操作;這違反了Liskov替換原則。因?yàn)椋琇iskov替換原則建議:對于客戶端程序ChartDrawer來說,drawChart()繪制行為使用的父類ChartComponent定義的對象是可以被其子類Bar或Line定義的對象完全替換,而不需要提供額外的子類信息。 違反Liskov替換原則的代碼具有以下缺陷:1)可擴(kuò)展性差。如果需要在圖2.11中添加新的圖表類型,比如餅狀圖Pie,則必須修改ChartDrawer類代碼,才能完成組件子類型的擴(kuò)展。而修改已有代碼將會導(dǎo)致一系列后果,詳細(xì)見本章2.2“開/閉”原則。2)引入程序邏輯錯誤。ChartDrawer類的行為drawChart()繪制的是ChartComponent類型的圖表組件;增加的新組件仍然是ChartComponent類型,但是drawChart()原有代碼卻無法完成新組件對象的繪制,其邏輯是錯誤的。 仔細(xì)觀察上面的代碼,學(xué)習(xí)者會發(fā)現(xiàn)違反Liskov替換原則的主要原因是:Bar子類
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 合唱服裝采購合同范例
- 中介合同范例里買
- 外貿(mào)貨物銷售合同范例
- 代課教師合同范例
- 商用房合租合同模板
- 合同范例源碼
- 樂高購銷合同范例
- 代購代加工合同范例
- 加盟服裝采購合同范例
- ice 系列合同范例
- 2024-2030年組氨酸行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 教育信息化教學(xué)資源建設(shè)規(guī)劃
- 屠宰場食品安全管理制度
- 部編版(2024秋)語文一年級上冊 6 .影子課件
- 2024秋期國家開放大學(xué)??啤缎淌略V訟法學(xué)》一平臺在線形考(形考任務(wù)一至五)試題及答案
- 基于SICAS模型的區(qū)域農(nóng)產(chǎn)品品牌直播營銷策略研究
- 病例討論英文
- 2024秋期國家開放大學(xué)??啤兑簤号c氣壓傳動》一平臺在線形考(形考任務(wù)+實(shí)驗(yàn)報告)試題及答案
- 【課件】植物體的結(jié)構(gòu)層次課件-2024-2025學(xué)年人教版生物七年級上冊
- 24秋國家開放大學(xué)《0-3歲嬰幼兒的保育與教育》期末大作業(yè)參考答案
- 相對濕度計算公式
評論
0/150
提交評論