在開發中,一直有這樣一種情境:App的未註冊用戶可使用部分功能(訪客視圖),一旦須要使用一些核心功能或者獲取個性化、差別化的服務時,就須要用戶登陸(登陸定製)。通常的狀況是:bash
用戶點擊某個按鈕 ——> 彈出登陸界面 ——> 輸入信息 ——> 登陸驗證 ——> 界面發生變化
複製代碼
在幾年前作開發時,因爲項目須要快速上線,因此顧不上思考(實際上是本身太菜),直接在須要判斷登陸的界面代碼裏寫上以下代碼:架構
BOOL isLogin;
if(self.isLogin){
//設置登陸後的界面
}
else{
//顯示訪客視圖
//若是用戶點擊登陸則跳轉登陸界面
//登陸完之後更新當前界面爲登陸後的界面
}
複製代碼
時間一長,代碼一多,就會發現不少界面有如上的重複代碼,這很顯然違背了Do not repeat yourself
的原則,並且跳轉的邏輯很煩。因而開始改進代碼。ide
最早的一個哥們兒的作法是將登陸字段抽取到一個常量中,須要時判斷該值是否爲真,而後執行相應的邏輯,這樣每一個類中就省去了一個字段。ui
if(CONSTANT.isLogin){
//設置登陸後的界面
}
else{
//顯示訪客視圖
//若是用戶點擊登陸則跳轉登陸界面
//登陸完之後更新當前界面爲登陸後的界面
}
複製代碼
隨着邏輯的增多,發現公用的代碼愈來愈多,因而抽取了父類,這樣邏輯就上移到了父類中,全部子類中不須要有相似isLogin
的屬性來判斷用戶是否登陸。atom
if(self.isLogin){
//設置登陸後的界面
}
else{
//顯示訪客視圖
//若是用戶點擊登陸則跳轉登陸界面
//登陸完之後更新當前界面爲登陸後的界面
}
複製代碼
忽然有一天,咱們發現某些App訪客視圖類似度很是大,某些App中的登陸界面也是同樣的,因此發現上面的代碼仍是須要精簡,因而咱們將上面的else部分
也上移到父類中,也就是在父類中判斷用戶是否登陸,未登陸顯示訪客視圖,而且將用戶是否登陸的字段isLogin
抽離到一個專門的用戶模型中。spa
下面以一個iOS的Demo來說解一下。 主題界面架構是這樣的:code
青色
,點擊中間的
+
彈出登陸界面,點擊登陸界面的
+
表示登陸過程,而後主界面顯示登陸後的各個界面,以不一樣顏色代替。
主界面的搭建代碼這裏就不貼了,很簡單,主要講解一下登陸與訪客的邏輯實現。orm
@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
複製代碼