资源泄漏:救援的命令模式
多年來(lái), 使用Plumbr進(jìn)行性能監(jiān)視時(shí),我遇到了數(shù)百個(gè)資源泄漏引起的性能問(wèn)題。 在這篇文章中,我想描述一種最簡(jiǎn)單的方法來(lái)清理資源并避免該問(wèn)題。
首先,我以電影播放器??應(yīng)用程序?yàn)槔齺?lái)描述問(wèn)題。 這種應(yīng)用程序的主要功能自然是在播放電影本身。 按照當(dāng)今的習(xí)慣,我們不想將整個(gè)電影收藏存儲(chǔ)在用于播放電影的設(shè)備上。 相反,我們將電影下載到本地臨時(shí)文件中,然后播放并刪除該文件以釋放下一部電影的空間。 這種工作流程的簡(jiǎn)單實(shí)施如下所示:
public class MoviePlayer {private final Catalog catalog = new Catalog();public void play(String movieName, String screen) {Movie movie = catalog.find(movieName);try {movie.fetch();movie.play(screen);} finally {movie.release();}} }class Catalog {Movie find(String name) {return new Movie(name);} }如您所見(jiàn), MoviePlayer類(lèi)是Catalog類(lèi)的客戶(hù)端,必須照顧電影播放的整個(gè)生命周期。 查找,下載,播放和刪除文件均屬于MoviePlayer類(lèi)的實(shí)現(xiàn)。
這是第一個(gè)問(wèn)題:如果至少一個(gè)這樣的客戶(hù)端是由某個(gè)粗心的開(kāi)發(fā)人員編寫(xiě)的,他們忘記調(diào)用movie.release()方法,則下載的文件將保留在本地磁盤(pán)上。 因此,您播放的每部電影都將添加一個(gè)文件,并且設(shè)備上的磁盤(pán)空間最終將被耗盡。
引入其他功能后,就會(huì)暴露出這種“萬(wàn)事通”代碼的第二個(gè)問(wèn)題。 例如,假設(shè)您需要增加記錄實(shí)際電影播放時(shí)間的可能性。
當(dāng)前唯一的方法是更改MoviePlayer類(lèi)。 如果Catalog類(lèi)有其他客戶(hù),則每個(gè)客戶(hù)都需要引入更改。 結(jié)果, MoviePlayer的每個(gè)附加功能都變得越來(lái)越大,處理越來(lái)越多的獨(dú)立問(wèn)題。 結(jié)果,代碼最終將難以理解和更改。
考慮到MoviePlayer應(yīng)該主要只是處理電影的播放,所以聽(tīng)起來(lái)確實(shí)有太多額外的麻煩。 確實(shí),因此讓我們嘗試將所有這些混亂的內(nèi)容從MoviePlayer中移出,以確保我們擁有一個(gè)負(fù)責(zé)任的班級(jí)。 命令設(shè)計(jì)模式是20年的技術(shù),最適合手頭的任務(wù)。
減輕痛苦:救援的命令模式
該方法背后的基本思想是首先抽象出因使用案例而異的操作,以使其與算法中更穩(wěn)定的部分區(qū)分開(kāi)。 在我們的情況下,這可能涉及電影播放或使用不同的視頻編解碼器進(jìn)行重新編碼。 因此,包括“查找電影-下載-執(zhí)行某些操作-刪除本地文件”的乏味步驟的樣板將與特定用例隔離。 在我們的示例中,我們可以使用以下簡(jiǎn)單界面執(zhí)行此操作:
上面的更改包括引入一種帶有MovieAction類(lèi)型的附加參數(shù)的新方法。 在此方法中,將執(zhí)行整個(gè)算法:
- 電影已找到。
- 電影已下載。
- 傳遞給該方法的動(dòng)作或命令在影片上執(zhí)行。 現(xiàn)在,特定操作是隨用例而變化的唯一可變部分。
- 最后,釋放電影的文件句柄并執(zhí)行對(duì)臨時(shí)文件的清理。
現(xiàn)在,如果需要以任何方式更改算法,我們將只在一個(gè)地方進(jìn)行操作,而不會(huì)影響仍?xún)H關(guān)注其特定動(dòng)作(例如電影播放或編碼)的任何客戶(hù)端。 現(xiàn)在,我們的MoviePlayer示例非常簡(jiǎn)單:
class Catalog {private Movie find(String name) {return new Movie(name);}void withMovie(String movieName, MovieCommand action) {Movie movie = find(movieName);try {movie.fetch();action.execute(movie);} finally {movie.release();}} }該技術(shù)非常強(qiáng)大且廣泛。 如果您尚未意識(shí)到此用途,請(qǐng)考慮對(duì)關(guān)系數(shù)據(jù)庫(kù)的JDBC訪(fǎng)問(wèn)。 所有與獲取數(shù)據(jù)庫(kù)連接,準(zhǔn)備語(yǔ)句,獲取結(jié)果集以及關(guān)閉資源有關(guān)的樣板文件,特別是在Spring Templating進(jìn)行救援之前,都是噩夢(mèng)般的處理順序。
同樣,可以通過(guò)使用命令模式,從不必要的樣板中清除代碼并大大簡(jiǎn)化代碼庫(kù),在自定義代碼庫(kù)中實(shí)現(xiàn)不同方面,例如安全檢查或緩存。
翻譯自: https://www.javacodegeeks.com/2016/09/resource-leakages-command-pattern-rescue.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的资源泄漏:救援的命令模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 电脑微信打不开怎么回事(电脑微信打不开怎
- 下一篇: openshift_为Openshift