您好,登錄后才能下訂單哦!
本篇內容主要講解“Java的設計模式怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java的設計模式怎么使用”吧!
設計模式是一種通過分割那些保持不變的部分和經常變化的部分,讓你的代碼更容易修改的方法。
不出意外的話,每個從事編程項目的人都可能會有同樣的思考。特別是那些工業級別的項目,在那里通常工作著數十甚至數百名開發者;協作過程表明必須有一些標準和規則來使代碼更加優雅并適應變化。這就是為什么我們有了 面向對象編程(OOP)和 軟件框架工具。設計模式有點類似于 OOP,但它通過將變化視為自然開發過程的一部分而進一步發展。基本上,設計模式利用了一些 OOP 的思想,比如抽象和接口,但是專注于改變的過程。
當你開始開發項目時,你經常會聽到這樣一個術語重構,它意味著通過改變代碼使它變得更優雅和可復用;這就是設計模式耀眼的地方。當你處理現有代碼時(無論是由其他人構建還是你自己過去構建的),了解設計模式可以幫助你以不同的方式看待事物,你將發現問題以及改進代碼的方法。
有很多種設計模式,其中單例模式、工廠模式和觀察者模式三種最受歡迎,在這篇文章中我將會一一介紹它們。
單例模式是非常流行的設計模式,它的實現相對來說很簡單,因為你只需要一個類。然而,許多開發人員爭論單例設計模式的是否利大于弊,因為它缺乏明顯的好處并且容易被濫用。很少有開發人員直接實現單例;相反,像 Spring Framework 和 Google Guice 等編程框架內置了單例設計模式的特性。
但是了解單例模式仍然有巨大的用處。單例模式確保一個類僅創建一次且提供了一個對它的全局訪問點。
單例模式:確保僅創建一個實例且避免在同一個項目中創建多個實例。
下面這幅圖展示了典型的類對象創建過程。當客戶端請求創建一個對象時,構造函數會創建或者實例化一個對象并調用方法返回這個類給調用者。但是每次請求一個對象都會發生這樣的情況:構造函數被調用,一個新的對象被創建并且它返回了一個獨一無二的對象。我猜面向對象語言的創建者有每次都創建一個新對象的理由,但是單例過程的支持者說這是冗余的且浪費資源。
Normal class instantiation
下面這幅圖使用單例模式創建對象。這里,構造函數僅當對象首次通過調用預先設計好的 getInstance()
方法時才會被調用。這通常通過檢查該值是否為 null
來完成,并且這個對象被作為私有變量保存在單例類的內部。下次 getInstance()
被調用時,這個類會返回第一次被創建的對象。而沒有新的對象產生;它只是返回舊的那一個。
Singleton pattern instantiation
下面這段代碼展示了創建單例模式最簡單的方法:
package org.opensource.demo.singleton; public class OpensourceSingleton { private static OpensourceSingleton uniqueInstance; private OpensourceSingleton() { } public static OpensourceSingleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new OpensourceSingleton(); } return uniqueInstance; } }
在調用方,這里展示了如何調用單例類來獲取對象:
Opensource newObject = Opensource.getInstance();
這段代碼很好的驗證了單例模式的思想:
鴻蒙官方戰略合作共建——HarmonyOS技術社區
當 getInstance()
被調用時,它通過檢查 null
值來檢查對象是否已經被創建。
如果值為 null
,它會創建一個新對象并把它保存到私有域,返回這個對象給調用者。否則直接返回之前被創建的對象。
單例模式實現的主要問題是它忽略了并行進程。當多個進程使用線程同時訪問資源時,這個問題就產生了。對于這種情況有對應的解決方案,它被稱為雙重檢查鎖,用于多線程安全,如下所示:
package org.opensource.demo.singleton; public class ImprovedOpensourceSingleton { private volatile static ImprovedOpensourceSingleton uniqueInstance; private ImprovedOpensourceSingleton() {} public static ImprovedOpensourceSingleton getInstance() { if (uniqueInstance == null) { synchronized (ImprovedOpensourceSingleton.class) { if (uniqueInstance == null) { uniqueInstance = new ImprovedOpensourceSingleton(); } } } return uniqueInstance; } }
再強調一下前面的觀點,確保只有在你認為這是一個安全的選擇時才直接實現你的單例模式。最好的方法是通過使用一個制作精良的編程框架來利用單例功能。
工廠模式是另一種眾所周知的設計模式,但是有一小點復雜。實現工廠模式的方法有很多,而下列的代碼示例為最簡單的實現方式。為了創建對象,工廠模式定義了一個接口,讓它的子類去決定實例化哪一個類。
工廠模式:將對象創建委派給工廠類,因此它能隱藏創建邏輯。
下列的圖片展示了最簡單的工廠模式是如何實現的。
Factory pattern
客戶端請求工廠類創建類型為 x 的某個對象,而不是客戶端直接調用對象創建。根據其類型,工廠模式決定要創建和返回的對象。
在下列代碼示例中,OpensourceFactory
是工廠類實現,它從調用者那里獲取類型并根據該輸入值決定要創建和返回的對象:
package org.opensource.demo.factory; public class OpensourceFactory { public OpensourceJVMServers getServerByVendor([String][18] name) { if(name.equals("Apache")) { return new Tomcat(); } else if(name.equals("Eclipse")) { return new Jetty(); } else if (name.equals("RedHat")) { return new WildFly(); } else { return null; } }}
OpenSourceJVMServer
是一個 100% 的抽象類(即接口類),它指示要實現的是什么,而不是怎樣實現:
package org.opensource.demo.factory; public interface OpensourceJVMServers { public void startServer(); public void stopServer(); public [String][18] getName();}
這是一個 OpensourceJVMServers
類的實現示例。當 RedHat
被作為類型傳遞給工廠類,WildFly
服務器將被創建:
package org.opensource.demo.factory; public class WildFly implements OpensourceJVMServers { public void startServer() { [System][19].out.println("Starting WildFly Server..."); } public void stopServer() { [System][19].out.println("Shutting Down WildFly Server..."); } public [String][18] getName() { return "WildFly"; }}
最后是觀察者模式。像單例模式那樣,很少有專業的程序員直接實現觀察者模式。但是,許多消息隊列和數據服務實現都借用了觀察者模式的概念。觀察者模式在對象之間定義了一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴它的對象都將被自動地通知和更新。
觀察者模式:如果有更新,那么訂閱了該話題/主題的客戶端將被通知。
理解觀察者模式的最簡單方法是想象一個郵件列表,你可以在其中訂閱任何主題,無論是開源、技術、名人、烹飪還是您感興趣的任何其他內容。每個主題維護者一個它的訂閱者列表,在觀察者模式中它們相當于觀察者。當某一個主題更新時,它所有的訂閱者(觀察者)都將被通知這次改變。并且訂閱者總是能取消某一個主題的訂閱。
如下圖所示,客戶端可以訂閱不同的主題并添加觀察者以獲得最新信息的通知。因為觀察者不斷的監聽著這個主題,這個觀察者會通知客戶端任何發生的改變。
Observer pattern
讓我們來看看觀察者模式的代碼示例,從主題/話題類開始:
package org.opensource.demo.observer; public interface Topic { public void addObserver([Observer][22] observer); public void deleteObserver([Observer][22] observer); public void notifyObservers();}
這段代碼描述了一個為不同的主題去實現已定義方法的接口。注意一個觀察者如何被添加、移除和通知的。
這是一個主題的實現示例:
package org.opensource.demo.observer; import java.util.List;import java.util.ArrayList; public class Conference implements Topic { private List<Observer> listObservers; private int totalAttendees; private int totalSpeakers; private [String][18] nameEvent; public Conference() { listObservers = new ArrayList<Observer>(); } public void addObserver([Observer][22] observer) { listObservers.add(observer); } public void deleteObserver([Observer][22] observer) { int i = listObservers.indexOf(observer); if (i >= 0) { listObservers.remove(i); } } public void notifyObservers() { for (int i=0, nObservers = listObservers.size(); i < nObservers; ++ i) { [Observer][22] observer = listObservers.get(i); observer.update(totalAttendees,totalSpeakers,nameEvent); } } public void setConferenceDetails(int totalAttendees, int totalSpeakers, [String][18] nameEvent) { this.totalAttendees = totalAttendees; this.totalSpeakers = totalSpeakers; this.nameEvent = nameEvent; notifyObservers(); }}
這段代碼定義了一個特定主題的實現。當發生改變時,這個實現調用它自己的方法。注意這將獲取觀察者的數量,它以列表方式存儲,并且可以通知和維護觀察者。
這是一個觀察者類:
package org.opensource.demo.observer; public interface [Observer][22] { public void update(int totalAttendees, int totalSpeakers, [String][18] nameEvent);}
這個類定義了一個接口,不同的觀察者可以實現該接口以執行特定的操作。
例如,實現了該接口的觀察者可以在會議上打印出與會者和發言人的數量:
package org.opensource.demo.observer; public class MonitorConferenceAttendees implements [Observer][22] { private int totalAttendees; private int totalSpeakers; private [String][18] nameEvent; private Topic topic; public MonitorConferenceAttendees(Topic topic) { this.topic = topic; topic.addObserver(this); } public void update(int totalAttendees, int totalSpeakers, [String][18] nameEvent) { this.totalAttendees = totalAttendees; this.totalSpeakers = totalSpeakers; this.nameEvent = nameEvent; printConferenceInfo(); } public void printConferenceInfo() { [System][19].out.println(this.nameEvent + " has " + totalSpeakers + " speakers and " + totalAttendees + " attendees"); }}
到此,相信大家對“Java的設計模式怎么使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。