隨著開發的迭代升級,不斷增加新的功能和職責,AppDelegate中的代碼量也不斷增長,致使Massive,而精通 OOP 的我們自然會想法子對其瘦身。
AppDelegate
什么是
AppDelegate
?
-
AppDelegate
是應用程序的根對象,即唯一代理:
a、其提供應用程序生命周期事件的暴露。
b、其確保應用程序與系統以及其他應用程序正確的交互。
c、其通常承擔很多職責,這使得很難進行更改,擴展和測試。 - 作為連接應用程序和系統的
協調者
,他應該總是:
a、單一職責
b、易于擴展
c、易于測試
組合模式
- 組合模式依據樹形結構來組合對象,用來表示部分以及整體層次。
a、它隸屬于結構型模式
b、主要分??組裝類
與??服務類
c、它近似于簡易SOA - 其作用體現為
a、服務易插拔
b、無需額外改變AppDelegate
實踐環節
- 樹節點(根節點):
組裝類
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface AppDelegateFactory : NSObject
@property (readonly) NSMutableArray *services;
+ (instancetype)standardFactory;
@end
NS_ASSUME_NONNULL_END
#import "AppDelegateFactory.h"
@interface AppDelegateFactory ()
@property (nonatomic, strong) NSMutableArray *services;
@end
@implementation AppDelegateFactory
+ (instancetype)standardFactory {
static AppDelegateFactory *insance = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{
insance = [AppDelegateFactory new];
});
return insance;
}
- (instancetype)init
{
self = [super init];
if (self) {
makeDefault(self);
}
return self;
}
NS_INLINE void makeDefault(AppDelegateFactory *factory) {
[factory registeService:@"ComponentLaunchService"];
// [factory registeService:@"ComponentPushService"];
// [factory registeService:@"ComponentBackgroundService"];
}
- (void)registeService:(NSString *)serviceClassString {
Class targetClass = NSClassFromString(serviceClassString);
NSObject *service = [[targetClass alloc] init];
if (![self.services containsObject:service])
[self.services addObject:service];
}
#pragma mark - Lazy load
/**
生命流程中,我們有時候需要保持調用順序,所以采用數組結構
*/
- (NSMutableArray *)services {
if (!_services) {
_services = [NSMutableArray array];
}
return _services;
}
@end
- 子節點(功能單元):
服務類
#import <UIKit/UIKit.h>
@interface ComponentLaunchService : NSObject <UIApplicationDelegate>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
@end
@implementation ComponentLaunchService
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/// launch your application
return YES;
}
- 植入流程
#import "AppDelegate.h"
#import "AppDelegateFactory.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
id<UIApplicationDelegate> service;
for(service in [AppDelegateFactory standardFactory].services){
///若服務響應
if ([service respondsToSelector:_cmd]) {
[service application:application didFinishLaunchingWithOptions:launchOptions];
}
}
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
id<UIApplicationDelegate> service;
for(service in [AppDelegateFactory standardFactory].services){
if ([service respondsToSelector:_cmd]){
[service applicationDidEnterBackground:application];
}
}
//程序進入后臺,通知服務器
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
id<UIApplicationDelegate> service;
for(service in [AppDelegateFactory standardFactory].services){
if ([service respondsToSelector:_cmd]){
[service applicationWillEnterForeground:application];
}
}
//程序從后臺進入前臺
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
id<UIApplicationDelegate> service;
for(service in [AppDelegateFactory standardFactory].services){
if ([service respondsToSelector:_cmd]){
[service applicationDidReceiveMemoryWarning:application];
}
}
//收到內存警告時
}
///..省略以下生命周期回調方法
@end
中介者模式
- 中介者模式提供一個中介類,該類通常處理不同類之間的通信。
a、其隸屬于行為型模式
b、支持松耦合 - 作用體現為:
a、使代碼易于維護
a、降低多個對象和類之間的通信復雜性
實踐環節
- 定義UIApplication的生命周期監聽者
import UIKit
class AppLifecycleMediator: NSObject {
private var listeners: [AppLifecycleListener]
init(listeners: [AppLifecycleListener]) {
self.listeners = listeners
super.init()
subscribe()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func subscribe() {
NotificationCenter.default.addObserver(self, selector: #selector(onAppDidFinishLaunching), name: UIApplication.didFinishLaunchingNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(onAppDidReceiveMemoryWarning), name: UIApplication.didReceiveMemoryWarningNotification, object: nil)
}
@objc private func onAppDidFinishLaunching() {
listeners.forEach { $0.onAppDidFinishLaunching() }
}
@objc func onAppDidReceiveMemoryWarning() {
listeners.forEach { $0.onAppDidReceiveMemoryWarning() }
}
}
- 定義監聽協議與實現者
import UIKit
protocol AppLifecycleListener {
func onAppDidFinishLaunching()
func onAppDidReceiveMemoryWarning()
}
extension AppLifecycleListener {
func onAppDidFinishLaunching() {}
func onAppDidReceiveMemoryWarning() {}
}
//MARK: - Listeners.. (舉個栗子)
class SocketListener: AppLifecycleListener {
func onAppDidFinishLaunching() {
print("[開啟長鏈接..]")
}
}
- 定義靜態方法,進行初始化
extension AppLifecycleMediator {
static func makeDefaultMediator() -> AppLifecycleMediator {
let socketListener = SocketListener()
return AppLifecycleMediator(listeners: [socketListener])
}
}
- 植入中介人
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
// point code
let mediator = AppLifecycleMediator.makeDefaultMediator()
///省略以下內容
}
優點在于
- 僅需要一次初始化
- 中介類自動訂閱事件
- 監聽者
Listener
易于增減、對AppDelegate
侵入弱
其實我們對
AppDelegate
都是維系代碼可維護度,職責的劃分,保證不會在部分修改時牽一發而動全身
,這樣使得代碼更靈活與茁壯,可隨時插拔與復用。
以上設計方式亦適用于,復雜模塊職能劃分,本文僅做簡單介紹與思考~??