發現問題與自我革命
在開發中,一直有這樣一種情境:App的未註冊使用者可以使用部分功能(訪客檢視),一旦需要使用一些核心功能或者獲取個性化、差異化的服務時,就需要使用者登入(登入定製)。一般的情況是:
使用者點選某個按鈕 ——> 彈出登入介面 ——> 輸入資訊 ——> 登入驗證 ——> 介面發生變化
複製程式碼
在幾年前做開發時,由於專案需要快速上線,所以顧不上思考(其實是自己太菜),直接在需要判斷登入的介面程式碼裡寫上如下程式碼:
BOOL isLogin;
if(self.isLogin){
//設定登入後的介面
}
else{
//顯示訪客檢視
//如果使用者點選登入則跳轉登入介面
//登入完以後更新當前介面為登入後的介面
}
複製程式碼
時間一長,程式碼一多,就會發現很多介面有如上的重複程式碼,這很顯然違背了Do not repeat yourself
的原則,而且跳轉的邏輯很煩。於是開始改進程式碼。
最先的一個哥們兒的做法是將登入欄位抽取到一個常量中,需要時判斷該值是否為真,然後執行相應的邏輯,這樣每個類中就省去了一個欄位。
if(CONSTANT.isLogin){
//設定登入後的介面
}
else{
//顯示訪客檢視
//如果使用者點選登入則跳轉登入介面
//登入完以後更新當前介面為登入後的介面
}
複製程式碼
隨著邏輯的增多,發現公用的程式碼越來越多,於是抽取了父類,這樣邏輯就上移到了父類中,所有子類中不需要有類似isLogin
的屬性來判斷使用者是否登入。
if(self.isLogin){
//設定登入後的介面
}
else{
//顯示訪客檢視
//如果使用者點選登入則跳轉登入介面
//登入完以後更新當前介面為登入後的介面
}
複製程式碼
突然有一天,我們發現某些App訪客檢視相似度非常大,某些App中的登入介面也是一樣的,所以發現上面的程式碼還是需要精簡,於是我們將上面的else部分
也上移到父類中,也就是在父類中判斷使用者是否登入,未登入顯示訪客檢視,並且將使用者是否登入的欄位isLogin
抽離到一個專門的使用者模型中。
摸著石頭過河
下面以一個iOS的Demo來講解一下。 主題介面架構是這樣的:
一開始,進入的時候,都顯示訪客介面,顏色為青色
,點選中間的+
彈出登入介面,點選登入介面的+
表示登入過程,然後主介面顯示登入後的各個介面,以不同顏色代替。
主介面的搭建程式碼這裡就不貼了,很簡單,主要講解一下登入與訪客的邏輯實現。
- 父類檢視控制器
@interface BaseViewController : UIViewController
@property (nonatomic, assign) BOOL isLogin;
@end
@implementation BaseViewController
-(void)loadView{
//UserModel是一個單例使用者類
self.isLogin = [UserModel shareInstance].isLogin;
//根據isLogin判斷使用者是否登入 如果未登入就顯示訪客檢視 否則就顯示正常介面
//但是注意 子檢視同樣需要在viewDidLoad中判斷使用者是否登入
//在登入介面 應該重新賦值window的rootViewController 重新整理控制器的狀態
self.isLogin ? [super loadView] : [self setupVisitorView];
}
-(void)setupVisitorView{
UIView *view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
view.backgroundColor = [UIColor cyanColor];
self.view = view;
}
@end
複製程式碼
- 子類檢視控制器(四個子類都差不多,這裡貼一個)
@implementation FourViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
if (self.isLogin) {
self.view.backgroundColor = [UIColor purpleColor];
}
}
@end
複製程式碼
- 中間檢視控制器
@implementation CenterViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:@"plusX_Last"] forState:UIControlStateNormal];
btn.bounds = CGRectMake(0, 0, 64, 64);
btn.center = self.view.center;
[self.view addSubview:btn];
if (!self.isLogin) {
self.title = @"未登入";
[btn addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
}
else{
self.title = @"已登陸";
[btn addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside];
}
}
-(void)login{
[UserModel shareInstance].isLogin = YES;
// 一定要重新賦值一次rootViewController
[self dismissViewControllerAnimated:YES completion:^{
[UIApplication sharedApplication].keyWindow.rootViewController = [[YFTabbarController alloc]init];
}];
}
-(void)close{
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
複製程式碼