可以先看看這個Demohttps://github.com/ming1016/DecoupleDemo。從這個Demo裡可以看到Controller和View還有Store的標頭檔案裡沒有任何Delegate,Block回撥,只有初始化和更新ViewModel的方法。所有這些控制元件,請求,ViewController和檢視之間的聯絡都是通過ViewModel來進行的,而viewModel也不進行任何邏輯處理,只是簡單的起到描述和預設值設定的作用。ViewController也被減輕的小得不能再小了,只需要初始化檢視和Store即可。這也是我的一次嘗試,看看如何利用KVO能夠做到最大限度的解耦,和最大限度的減少程式碼和介面。
可以先看看以前程式碼最臃腫的地方在使用了新的思路後會變成怎麼樣,首先是ViewController
1 2 3 4 5 6 |
- (void)viewDidLoad { [super viewDidLoad]; [self addKVO]; [self buildConstraints]; self.tbStore = [[TestTableStore alloc] initWithViewModel:self.tbView.viewModel]; } |
可以看到裡面僅僅做了新增KVO,佈局控制元件和初始化Store的工作。
封裝的TableView作為一個通用控制元件是不會去設定管理不同的Cell的,可以看看不用Delegate和Block是如何處理的。
1 2 3 4 5 6 |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { self.viewModel.tableViewIdentifier = smTableViewIdentifier; self.viewModel.tableView = tableView; self.viewModel.cellIndexPath = indexPath; return self.viewModel.cell; } |
我覺得這樣應該很簡化了。當觸發到UITableView這個配置Cell的回撥時,通過對ViewModel的鍵值的監聽就能夠在任何地方對Cell進行配置了,而不用通過繁瑣的Delegate和Block來層層回撥了。
除了這裡外,其它地方也用同樣的方法進行了處理,比如說對新出現訊息提示點選使其消失只需要設定ViewModel裡的isHideHintView的值的處理,還有對請求不同狀態顯示不同引導頁,只要是以前需要通過介面和回撥的全部幹掉,用ViewModel去控制,下面可以看看我寫的ViewModel中,我將KVO分成了View Side和Data Side,前者主要是響應檢視方面的邏輯變化,後者Data Side是響應不同的動作來產生對資料不同的處理,其它就都是些關於樣式和資料配置相關的了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//--------------------------- // KVO View Side //--------------------------- @property (nonatomic, assign) BOOL isHideGuideView; //是否顯示guide view @property (nonatomic, assign) BOOL isHideHintView; //是否顯示hint view //下拉重新整理上拉載入更多 @property (nonatomic, assign) SMTableRequestStatus requestStatus; //重新整理狀態 //TableView Delegate //通用 @property (nonatomic, strong) UITableView *tableView; @property (nonatomic, strong) NSString *tableViewIdentifier; //Cell @property (nonatomic, strong) NSIndexPath *cellIndexPath; @property (nonatomic, strong) UITableViewCell *cell; //CellHeight @property (nonatomic, strong) NSIndexPath *cellHeightIndexPath; @property (nonatomic, assign) CGFloat cellHeight; //--------------------------- // KVO Data Side //--------------------------- @property (nonatomic, assign) SMTableRefreshingStatus dataSourceRefreshingStatus; //請求狀態 |
縱觀整個專案,標頭檔案都很乾淨,唯一有方法需要引數的也就是ViewModel。這種完全物件導向思路的程式設計方式在需求經常變更的情況下優勢就會慢慢顯露出來,對吧。