使用objection來模組化開發iOS項目

來源:互聯網
上載者:User

使用objection來模組化開發iOS項目

objection 是一個輕量級的依賴注入架構,受Guice的啟發,Google Wallet 也是使用的該項目。「依賴注入」是物件導向編程的一種設計模式,用來減少代碼之間的耦合度。通常基於介面來實現,也就是說不需要new一個對象,而是通過相關的控制器來擷取對象。2013年最火的PHP架構 laravel 就是其中的典型。

 假設有以下情境:ViewControllerA.view裡有一個button,點擊之後push一個ViewControllerB,最簡單的寫法類似這樣:
  1. - (void)viewDidLoad 
  2.     [super viewDidLoad]; 
  3.     UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; 
  4.     button.frame = CGRectMake(100, 100, 100, 30); 
  5.     [button setTitle:@"Button" forState:UIControlStateNormal]; 
  6.     [button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside]; 
  7.     [self.view addSubview:button]; 
  8.  
  9. - (void)buttonTapped 
  10.     ViewControllerB *vc = [[ViewControllerB alloc] init]; 
  11.     [self.navigationController pushViewController:vc animated:YES]; 
這樣寫的一個問題是,ViewControllerA需要import ViewControllerB,也就是對ViewControllerB產生了依賴。依賴的東西越多,維護起來就越麻煩,也容易出現循環相依性的問題,而objection正好可以處理這些問題。 實現方法是:先定義一個協議(protocol),然後通過objection來註冊這個協議對應的class,需要的時候,可以擷取該協議對應的object。對於使用方無需關心到底使用的是哪個Class,反正該有的方法、屬性都有了(在協議中指定)。這樣就去除了對某個特定Class的依賴。也就是通常所說的「面向介面編程」。
  1. JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1] 
  2. UIViewController  *vc = [injector getObject:@protocol(ViewControllerAProtocol)]; // [2] 
  3. vc.backgroundColor = [UIColor lightGrayColor]; // [3] 
  4. UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc]; 
  5. self.window.rootViewController = nc; 
[1] 擷取預設的injector,這個injector已經註冊過ViewControllerAProtocol了。[2] 擷取ViewControllerAProtocol對應的Object。[3] 拿到VC後,設定它的某些屬性,比如這裡的backgroundColor,因為在ViewControllerAProtocol裡有定義這個屬性,所以不會有warning。 可以看到這裡沒有引用ViewControllerA。再來看看這個ViewControllerAProtocol是如何註冊到injector中的,這裡涉及到了Module,對Protocol的註冊都是在Module中完成的。Module只要繼承JSObjectionModule這個Class即可。
  1. @interface ViewControllerAModule : JSObjectionModule 
  2. @end 
  3.  
  4. @implementation ViewControllerAModule 
  5. - (void)configure 
  6.     [self bindClass:[ViewControllerA class] toProtocol:@protocol(ViewControllerAProtocol)]; 
  7. @end 
 綁定操作是在configure方法裡進行的,這個方法在被添加到injector裡時會被自動觸發。
  1. JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1] 
  2. injector = injector ? : [JSObjection createInjector]; // [2] 
  3. injector = [injector withModule:[[ViewControllerAModule alloc] init]]; // [3] 
  4. [JSObjection setDefaultInjector:injector]; // [4] 
[1] 擷取預設的 injector[2] 如果預設的 injector 不存在,就建立一個[3] 往這個 injector 裡註冊我們的 Module[4] 設定該 injector 為預設的 injector 這段代碼可以直接放到 + (void)load裡執行,這樣就可以避免在AppDelegate裡import各種Module。 因為我們無法直接獲得對應的Class,所以必須要在協議裡定義好對外暴露的方法和屬性,然後該Class也要實現該協議。
  1. @protocol ViewControllerAProtocol  
  2. @property (nonatomic) NSUInteger currentIndex; 
  3. @property (nonatomic) UIColor *backgroundColor; 
  4. @end 
  5.  
  6. @interface ViewControllerA : UIViewController  
  7. @end 
 通過objection實現依賴注入後,就能更好地實現SRP(Single Responsibility Principle),代碼更簡潔,心情更舒暢,生活更美好。拿Pinterest來說,下面的頁面就可以劃分為3個Section。各個Section可以由不同的人負責,然後串到一起就行,也能一定程度地避免MVC(Mess View Controller)的出現。 總體來說,這個lib還是挺靠譜的,已經維護了兩年多,也有一些項目在用,對於提高開發成員的效率也會有不少的協助,可以考慮嘗試下。

CocoaChina是全球最大的蘋果開發中文社區,官方每日定時推送各種精彩的研發教程資源和工具,介紹app推廣營銷經驗,最新企業招聘和外包資訊,以及Cocos2d引擎、Cocos Studio開發套件的最新動向及培訓資訊。關注可以第一時間瞭解最新產品和服務動態,在手,天下我有!


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.