任浩然,劉 丹
(延安職業(yè)技術學院 陜西 延安 716000)
計算機軟件設計和開發(fā)為人們的學習、生活、工作帶來了極大的便利,計算機技術的快速發(fā)展,軟件變得越來越復雜,軟件中的數(shù)據(jù)和數(shù)據(jù)結構是基本的運行資源,操作數(shù)據(jù)和數(shù)據(jù)結構的邏輯通常是算法,數(shù)據(jù)和算法組成的一個邏輯整體即是軟件。數(shù)據(jù)通過獨立的變量或者函數(shù)參數(shù)在傳遞或者流動,整個程序是線性地去組織和構成的。數(shù)據(jù)類型和具體的數(shù)據(jù)來定義變量,算法的代碼邏輯來定義函數(shù)。兩者之間沒有必然的關聯(lián)。在整個程序的主入口調試代碼可以看到數(shù)據(jù)是如何在數(shù)據(jù)結構和算法的控制下流動的,函數(shù)一般可以將輸入?yún)?shù)、輸出數(shù)據(jù)、預期操作和算法表達清楚。編程方法面對整個處理過程更符合一般的線性的邏輯思維,但隨著軟件系統(tǒng)模塊的增加,數(shù)據(jù)、數(shù)據(jù)結構和算法邏輯之間的關聯(lián)關系成幾何倍數(shù)的增加,程序的數(shù)據(jù)、數(shù)據(jù)結構和算法定義和編寫也變得越來越困難。為了解決此問題,面向對象的編程語言[1]的設計思想出現(xiàn),程序設計時,首先考慮系統(tǒng)中的對象,對象間直接的關系,對象之間的交互關系,確定對象的數(shù)據(jù)域。盡管面向對象的方式可以減少軟件系統(tǒng)中面向過程編程所帶來的復雜性問題,但由于類中的方法中的編程模式實際上還是面向過程的編碼,因此需要一定的設計模式對軟件系統(tǒng)進行解耦和復用,減少Java編程開發(fā)軟件過程中復雜性膨脹與蔓延的情況。
Java編程語言的簡單和穩(wěn)定性體現(xiàn)在Java程序運行之前會進行代碼的安全性檢查,不支持goto語句,取消了指針的的語法,不需要關注內存分配和回收方面的問題。移除了指針的概念和其相關的操作,指針的操作可以自由移動并任意的讀取和存放操作系統(tǒng)的內存地址。不管這個內存地址存儲著的數(shù)據(jù)是否重要或正在被其他系統(tǒng)軟件使用,經常有越界使用讀寫內存地址的數(shù)據(jù)導致了整個操作系統(tǒng)崩潰的情況,Java特定的垃圾回收方式,不需要程序員直接去控制內存對象的回收,從而極大地避免了危險的操作,提高了穩(wěn)定性。除此之外定義后的變量只有在滿足強制轉換規(guī)則的情況下才能強轉成功。在運行時的環(huán)境提供了穩(wěn)定性保障機制,如字節(jié)碼校驗器、類裝載器、運行時內存模型校驗、文件訪問限制等,Java在字節(jié)碼的傳輸過程中還使用了公開密鑰加密機制(PKC),進一步地提高了底層的穩(wěn)定性。
面向對象是更加符合人的思維模式的,使用面向對象的方式開發(fā)軟件編寫程序更具有可讀性,在現(xiàn)實生活中一個對象的屬性和行為可以封裝成一個類,把具體的業(yè)務邏輯功能實現(xiàn)封裝成具體的方法,方法代碼塊中可以訪問類中的變量和實例變量,私有的變量可以通過公有的方法進行設置和獲取。所有的子類所共有的行為和屬性抽取為一個父類,所有的子類繼承該類可具備父類的屬性和行為,繼承具有單一性和傳遞性。這是代碼的復用的一種有效方式。運行時類型由實際賦給該變量的對象決定,因此表現(xiàn)出子類對象特有的方法,多個類進行修改和擴展新功能時,父類的代碼不會變更,只需要在子類的重寫的方法中修改自身的業(yè)務邏輯即可,因為面向對象的特點,所有的擴展變得更加的簡潔,符合人的思維習慣。
Java語言對多線程提供了極大的支持,線程對象一般是異步的搶占CPU等待著CPU的調度后執(zhí)行,如果中間的細節(jié)全部交給程序員自己進行維護和管理,每個線程對象的私有程序計數(shù)器和堆棧以及CPU指令的地址都需要通盤考慮,及其容易將CPU指令的時序混淆容易產生死鎖等性能問題。Java內置了多線程的操作維護管理的機制,這種機制使得程序員能夠很簡潔地編寫多線程任務。Java的所有內置的類庫,都有對應的多線程包裝的類,利用多線程的機制線程對線程中創(chuàng)建、就緒、運行、阻塞以及死亡等狀態(tài)之間進行方便的切換。Java有一定的動態(tài)性,可以利用反射機制來獲取類似于動態(tài)語言的特性,Java的特殊情形的動態(tài)性讓其編程的時候更加靈活。
平臺無關是Java編程語言的一個優(yōu)勢,平臺主要考慮軟件平臺和硬件平臺,軟件運行時的環(huán)境不會對程序的運行造成兼容性之類的影響,導致程序出現(xiàn)異?;蛘邟炱鸬默F(xiàn)象,系統(tǒng)軟件如操作系統(tǒng)的變化不會影響程序的正常運行。硬件平臺一般是處理器平臺的架構,無論是Intel的復雜指令集還是Arm的精簡指令集,在不同的處理器硬件平臺間進行移植可以做到運行結果一致。主要的原理是JVM把Java的源代碼編譯成了以class后綴結尾的中間代碼,JVM再將中間代碼翻譯成所在的具體的不同軟硬件平臺的機器碼,并驅動平臺執(zhí)行該平臺對應的機器碼。
實際開發(fā)中Java語言在絕大部分的B/S情況下只是在處理M(Model)+C(Controller)的邏輯,而從概念上來看,M代表的就是數(shù)據(jù)模型、而C則僅僅是一種控制層邏輯,MVC的軟件開發(fā)的架構,簡單的描述了軟件的View層,主要負責展示當觀察者到模型M層的變化,便使用一定的策略來組合C層的業(yè)務邏輯,包含了觀察者模式、組合模式和策略模式,MVC模式中的M不僅僅代表的是數(shù)據(jù)模型,而是包括了數(shù)據(jù)模型之內的所有業(yè)務邏輯相關的代碼,而C則是比較輕量級的,它被賦予只有處理輸入/輸出參數(shù)以及對該請求進行邏輯流程控制的職能,如果Java代碼中對C層有過重的邏輯代碼侵入,這是不符合MVC架構規(guī)范的。構建復雜的軟件系統(tǒng)只有遵循一定的設計原則并合適地運用相應的設計模式,這樣的Java代碼才不至于在復雜的邏輯中迷失方向。
基于Spring MVC框架[2]的開發(fā)中,C層作為服務的入口主要承擔接收和轉換由終端層或者其他服務發(fā)送的網絡請求,并將其轉化為Java數(shù)據(jù)對象,然后對數(shù)據(jù)對象進行參數(shù)合法性校驗,之后通過在C依賴注入對應Service層服務接口,并進行業(yè)務邏輯層方法調用,如果業(yè)務邏輯并不復雜,那么可以直接操作數(shù)據(jù)庫持久層完成業(yè)務邏輯;而如果Service層方法發(fā)現(xiàn)非常多的邏輯條件每個條件所需要處理的代碼量超過一定的規(guī)模,那么此時通過Factory工廠模式拆分不同的業(yè)務處理邏輯,而對于公共的處理邏輯則可以通過抽象類定義抽象方法進行抽象。類通常一開始很小,但是隨著程序的增長而逐漸膨脹。一個類應該只賦予它一個職責。如果它所承擔的職責太多,就需要抽象公共的業(yè)務邏輯使得代碼“減負”。復雜性[3]的含義一般是指任何在軟件中難于理解和修改的邏輯。含義模糊的代碼和互相依賴模塊是最主要的復雜性來源。代碼里面的重要信息不是顯而易見的,如果不結合其他模塊,就會無法理解代碼的真實含義。在大多數(shù)情況下,分割過大的類可以避免代碼和功能的重復。使用類似觀察者模式、組合模式、策略模式以及工廠模式等的設計模式可以減少重復的代碼,提高表達力,提早構建簡單抽象的軟件結構,使得代碼變得整潔可理解,不再復雜。
綜上所述,傳統(tǒng)的面向過程的編程方法的復雜性隨著系統(tǒng)的規(guī)模增加會呈幾何倍數(shù)的增加,為了降低編程過程中系統(tǒng)的復雜性,Java的面向對象的特性可以減少開發(fā)軟件過程中復雜性膨脹與蔓延的情況,此外使用諸如觀察者模式、組合模式、策略模式以及工廠模式等的設計模式和MVC的架構可以減少重復的代碼,找出易變化的部分,合理抽象,用抽象構建框架、用實現(xiàn)擴展細節(jié)。對擴展開放,對修改關閉。在軟件需要進行拓展的時候,不去修改原有的代碼,降低了軟件開發(fā)過程中引入的復雜性。