2013-10-04 33 views
3

許多Android應用程序都包含一個自己的BaseActivity類,該應用程序中的所有活動都會擴展。這非常有用,因爲它提供了一箇中心位置來放置大多數/所有活動中常見的功能。擁有BaseActivity的主要缺點是您無法使用任何Activity子類(ListActivity等)。委派經理是否有良好的設計理念?

一種替代方法是有一個ActivityDelegate。這爲功能提供了一箇中心位置,同時仍然允許您使用Activity子類。這也可以說是更可測試的,因爲它使用組合而不是繼承。

當BaseActivity/ActivityDelegate變得過大和複雜時,這兩種解決方案都可能導致大量的意大利麪代碼。對此的一個可能的解決方案是使用委託模式,但將功能分成許多不同的代表。這減少了委託中的意大利麪代碼,但是這些活動變得更加複雜 - 他們現在試圖將他們的*方法轉發給許多不同的代表,而不是僅僅一個。

所有這些問題的可能解決方案是使用委託管理器。代表經理跟蹤應用程序中所有較小的代表。活動將他們的*方法轉發給代理經理,代理經理將其轉發給所有單獨的代表。這實現了以下所有條件:

  • 進行重複數據刪除代碼 - 所有常用的功能被放置到代表之一
  • 允許使用活動的子類中的所有活動
  • 簡單的代碼 - 所有的*方法被轉發到只是一類
  • 容易測試 - 這是簡單的模擬出周圍的代表和代表經理家居單元測試

有沒有人使用這種模式befor試圖è?如果是這樣,它是怎麼回事?

回答

2

據我所知,你在談論整個應用程序的一個單一的DelegateManager對象。如果是這樣的話,你可以使用registerActivityLifecycleCallbacks,看到http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29

如果你在< API級別,你需要看看14:https://github.com/BoD/android-activitylifecyclecallbacks-compat

registerActivityLifecycleCallbacks可讓您勾選XXXX生命週期方法的活動。

當然這樣做有您所描述的所有優點:

  • 解耦是可用的,只有當你真正需要重複的行爲是有點很少的控制器+視圖邏輯捆綁在了一起活動的工作方式。
  • 如果您有可能重複使用的活動,刪除繼承很不錯 - 但我以前從未做過。但我想一個好的用例可能是您處理設置或其他需要應用程序的行爲的自制活動。

在我的頭頂,我可以把這些缺點的:

  • 使用偵聽所有的地方可以虛化應用活動/調用層級的路徑,並可以使代碼很難理解。這適用於所有監聽器/調度器類型的編程。這是一個強大的工具,但要小心處理。
  • 它可以引入很多(如你所說)樣板/意大利麪代碼,如果你只是傳遞給生命週期的聽衆/代表。
  • 您有責任通過Application.unregisterActivityLifecycleCallbacks從申請中取消註冊。我不認爲有它周圍的一個很好的方式,

我個人沒有用過這種設計模式多的生命週期,但它可能是值得一些使用情況。例如:

  • ApplicationLifecycleLogger:每次創建/恢復/暫停...活動時,logcat或其他使調試生命週期變得更容易一點。
  • 如果某人因爲某種模型狀態(例如響鈴警報 - >無法進入AlarmEditActivity)而不允許進入某項活動,則可以在該處完成()。
  • 在沒有Parcelable:s和屏幕旋轉更改的情況下跨活動邊界傳遞對象狀態。通常這是通過應用程序中的Map或某個靜態字段來實現的。你可以通過讓代理人持有狀態來做到這一點。

此外,看一看:Is there a design pattern to cut down on code duplication when subclassing Activities in Android?

我希望這是有幫助=)

+0

感謝您的答覆。我對這種模式的一個主要需求是在網絡加載失敗時顯示「網絡錯誤」屏幕。我在活動和片段中都使用網絡資源,因此我需要使用相同的屏幕才能顯示這兩者。通過委託,我可以將所有代碼顯示爲一個網絡錯誤。如果我要使用繼承,我需要一個BaseActivity,然後我假設一個BaseFragment,它們都包含非常相似的代碼。你有沒有碰到這個用例?如果是這樣,你是否能夠通過繼承來處理它而不會重複代碼? – Mark

+0

我很抱歉這個遲到的回覆。 「網絡錯誤」似乎是一個合法的使用案例 - 它與「ApplicationLifecycleLogger」有些相似,因爲它在基於網絡的應用程序中的大多數活動中都會使用它。就個人而言,我還沒有寫這樣的應用程序,所以我還沒有遇到它。 – Centril