現在很多的大型項目基本都是多人協作的,基本都是以組件化開發為主,減少不同開發人員之間的相互影響,小中型項目有沒有必須使用呢,有人說沒必要,殺雞焉用牛刀,其實是有必須要的,雖然代碼量有增加,但是最起碼代碼結構更清晰,也利於代碼維護,如果去做大型項目也能提早適應,再者也是對編碼能力的提升,好處很多啊。
下面從swift開發iOS為例來做個介紹。
AppDelegate是iOS開發中一個很重要的類,很多系統的事件處理都在這個類下,如推送,分享,支付等等,這個類加太多的處理會導致很臃腫,有人建議說可以用分類,這也是一種辦法,
分類有一個不好的地方就是會導致代碼分散,閱讀性會差一些。從設計模式的6大原則來解決問題,可以有其它的解決方案。AppDelegate下相關的代理還是寫在其下,AppDelegate只做粘合作用,其它不同的業務需要單獨處理,定義到自己的業務類中。
項目中的MCHKit文件夾只做共用代碼包,與業務無關,拿到任何項目中都可以拿來直接使用,並不會報錯。下面以推送功能為例.
在項目的MCHKit下創建 ModuleManager,RemotePushMoudel類,包含一個ModuleManagerDelegate 協議,業務類需要實現ModuleManagerDelegate協議,作為業務組件和AppDlegate通信的橋梁。
所有組件的基類

具體實現,定義一個ModuleManager.swift
// SwfitDemo
// Created by menchao on 2018/9/26.
// Copyright © 2018年 cedarhd. All rights reserved.
import UIKit
@objc public protocol ModuleManagerDelegate {
@objc optional func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplicationLaunchOptionsKey : Any]?)
//其它的處理。。。
func applicationWillResignActive(_ application: UIApplication)
func applicationDidEnterBackground(_ application: UIApplication)
}
public class ModuleManager : NSObject{
static let sharedInstace = ModuleManager.init()
private override init(){
}
public func loadModule(_ module: ModuleManagerDelegate? ){
if((module) != nil){
self.allModules.append(module!)
}
}
public func loadAllModule(_ modules:[Array<ModuleManagerDelegate>]?){
if((modules) != nil){
self.allModules.removeAll()
for item in modules!{
self.allModules.append(item as! ModuleManagerDelegate)
}
}
}
// MARK: - app delegate
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplicationLaunchOptionsKey : Any]?){
for service in self.allModules {
let serviceDelegate = service
if serviceDelegate.application != nil{
serviceDelegate.application!(application, didFinishLaunchingWithOptions: launchOptions)
}
}
}
lazy var allModules: Array<ModuleManagerDelegate> = {
var array = Array<ModuleManagerDelegate>()
return array
}()
}
ModuleManagerDelegate里的名稱可以改為自己的名稱,為了和系統相呼應,建議和系統保持一樣的名字。
定義一個推送消息模塊RemotePushMoudel,繼承ModuleManagerDelegate,用來處理協議方法。如下,把推送相關的處理用extension定義,減少AppDelegate的臃腫import UIKit
class RemotePushMoudel:NSObject, ModuleManagerDelegate {
var delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]?){
print("TestRemotePush 實現 application")
self.registerAppNotificationSettings(launchOptions: launchOptions)
}
func registerAppNotificationSettings(launchOptions: [UIApplicationLaunchOptionsKey : Any]?) {
if #available(iOS 10.0, *) {
let notifiCenter = UNUserNotificationCenter.current()
notifiCenter.delegate = self
let types = UNAuthorizationOptions(arrayLiteral: [.alert, .badge, .sound])
notifiCenter.requestAuthorization(options: types) { (flag, error) in
if flag {
print("iOS request notification success")
}else{
print(" iOS 10 request notification fail")
}
}
} else {
let setting = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
UIApplication.shared.registerUserNotificationSettings(setting)
}
UIApplication.shared.registerForRemoteNotifications()
}
// MARK: - RemoteNotification
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Swift.Void){
}
@available(iOS 10.0, *)
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void){
}
}
定義一個業務類PushBusiness,這個類可以專門處理推送相關的業務邏輯,實現如下:
import UserNotifications
// MARK: - push extension
extension AppDelegate{
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("deviceToken: \(deviceToken)")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error){
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]){
//方法1.此處處理推送業務邏輯 具體的業務實現
//do something
//方法2. 為了減少耦合,也可以把業務邏輯單獨定義實現
PushBusiness.oneBusinessReceiveRemotePush(userInfo: userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
}
}
//業務處理
class PushBusiness: NSObject {
class func oneBusinessReceiveRemotePush(userInfo: [AnyHashable : Any]) {
print("userInfo: \(userInfo)")
//處理具體推送業務
}
}
定義完了以上,下一步用一個類管理所有的業務,定義 ServiceComponentManager 如下:
import UIKit
public class ServiceComponentManager {
public class func registerAllService(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplicationLaunchOptionsKey : Any]?){ /// add all Moudel //push let pushModule = RemotePushMoudel() ModuleManager.sharedInstace.loadModule(pushModule) //添加其它 //pay //other ModuleManager.sharedInstace.application(application,didFinishLaunchingWithOptions: launchOptions) } }
以上定義好了后,直接在AppDelegate的入口方法添加即可。
class AppDelegate: UIResponder, UIApplicationDelegate ,UNUserNotificationCenterDelegate{
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.backgroundColor = UIColor.white
self.window?.rootViewController = RootTabBarController()
self.window?.makeKeyAndVisible()
//注冊服務模塊
ServiceComponentManager.registerAllService(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
}
通過以上說明,可以做到對AppDelegate組件化分解,減少AppDelegate的臃腫,這樣定義耦合性就很低了,不同的業務互不干擾,方便維護。如果項目需要增加如分享,支付等,都可以使用類似方法,如果想在不同的項目中復用RemotePushMoudel,還可以在改造,RemotePushMoudel放到MCHKit中,業務代碼抽離到業務模塊類,可以通過通知或delegate等來實現。 雖然代碼量稍有增加,但是可讀性更強,同時也做到了高內聚,低耦合。
