本文試圖探討以下三個(gè)問題
- 什么是類簇
- 使用類簇有什么好處
- 類簇的具體應(yīng)用
1. 什么是類簇
類簇的英文名是class cluster,cluster本意是一群,一組的意思,簡單的說類簇就是一組類,是一組什么什么樣的類呢? 官方文檔是這么說的:
A class cluster is an architecture that groups a number of private, concrete subclasses under a public, abstract superclass. The grouping of classes in this way provides a simplified interface to the user, who sees only the publicly visible architecture.
大概意思就是說類簇模式是包含了一組私有的具體的類,這些類繼承一個(gè)公開的抽象類,也即是基類,基類負(fù)責(zé)提供對外接口供調(diào)用者使用,具體類負(fù)責(zé)方法的真正實(shí)現(xiàn), 我們只需要調(diào)用基類提供的接口來實(shí)現(xiàn)相關(guān)功能,而無需關(guān)心背后的具體實(shí)現(xiàn)細(xì)節(jié)。
用代碼表示如下:
// 基類提供一個(gè)工廠方法返回具體的實(shí)例對象
[AbstractClass *concreteObj] = [AbstractClass ClasssWithType:type]
// 調(diào)用基類提供的方法
[concreteObj AbstractClassMehod]
舉個(gè)例子在UIButton這個(gè)類下面有一個(gè)工廠方法
(UIButton *)buttonWithType:(UIButtonType)Type,調(diào)用這個(gè)方法可以返回具體的實(shí)例類,此時(shí)UIbutton就是一個(gè)抽象的基類,返回的是他子類的實(shí)例,然后我們再調(diào)用基類提供的接口完成相關(guān)邏輯
// 返回子類的實(shí)例
UIButton *button = [UIButtonbuttonWithType:UIButtonTypeRoundedRect];
// 我們只需要調(diào)用基類提供的方法,而不關(guān)心具體子類的實(shí)現(xiàn)
[button setImage:[UIImage imageNamed:@"1.png"] forState:UIControlStateNormal];**
假設(shè)一下如果沒有使用類簇模式的話,上面的代碼可能寫成
RoundedRectButton *button =[RoundedRectButton alloc] init];
[button setImage:[UIImage imageNamed:@"1.png"] forState:UIControlStateNormal]
假如子類很多, 我們需要針對每個(gè)子類都有一種寫法,如下圖所示
使用類簇有什么好處?
至此我們大概可以知曉,使用類簇對于開發(fā)者而言很方便維護(hù)和拓展,具體的實(shí)現(xiàn)代碼放在對應(yīng)的子類里,假如我們想再拓展,只需要繼承子類,重寫對外的接口即可,對于調(diào)用者而言十分簡單明了,不用去關(guān)心子類是如何實(shí)現(xiàn),只需要調(diào)用基類提供的接口即可。
具體實(shí)踐
到了愉快的碼代碼時(shí)間了,假設(shè)我們接到一個(gè)需求
用戶點(diǎn)擊下載按鈕,如果下載成功顯示成功的提醒,下載失敗顯示一個(gè)按鈕允許用戶點(diǎn)擊后再次下載,那么我們可以按照下列實(shí)現(xiàn)
思路:
1.創(chuàng)建一個(gè)基類HintView,實(shí)現(xiàn)一個(gè)工廠方法,根據(jù)傳入的不同值生成不同的的子類實(shí)例 ,并定義一個(gè) showToView: 接口,由子類具體實(shí)現(xiàn)方法
2.創(chuàng)建兩個(gè)子類SuccessHintView,F(xiàn)ailHintView,分別根據(jù)下載成功和失敗的情況實(shí)現(xiàn)具體的showshowToView:方法
具體實(shí)現(xiàn),
1.定義一個(gè)基類
HintView.h
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger,HintViewType){
HintViewTypeSuccess,
HintViewTypeFail
};
@interface HintView : NSObject
+ (HintView *)viewWithType:(HintViewType)type;
- (void)showToView:(UIView *)view;
@end
HintView.m
@implementation HintView
+ (HintView *)viewWithType:(HintViewType)type{
HintView *view = nil;
switch (type) {
case HintViewTypeSuccess:{
view= [[SuccessHintView alloc] init];
break;
}
case HintViewTypeFail:{
view= [[FailHintView alloc] init];
break;
}
}
return view;
}
- (void)showToView:(UIView *)view {
// subClass implement this
};
2.然后分別在對應(yīng)的子類實(shí)現(xiàn)方法
SuccessHintView.m文件
#import "SuccessHintView.h"
@implementation SuccessHintView
- (void)showToView:(UIView *)view{
CGPoint center = view.center;
UILabel *lable = [[UILabel alloc] init];
lable.frame = CGRectMake(0, 0, 200, 200);
lable.center = center;
lable.textAlignment = NSTextAlignmentCenter;
lable.backgroundColor = [UIColor redColor];
[view addSubview:lable];
lable.text = @"恭喜你下載成功";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[lable removeFromSuperview];
});
}
FailHintView.m文件
#import "FailHintView.h"
@implementation FailHintView
- (void)showToView:(UIView *)view{
CGPoint center = view.center;
UIButton *button = [[UIButton alloc] init];
button.frame = CGRectMake(0, 0, 200, 100);
button.center = center;
[view addSubview:button];
[button setTitle:@"下載失敗,點(diǎn)擊我重試" forState:UIControlStateNormal];
button.backgroundColor = [UIColor redColor];
[button addTarget:self action:@selector(didCLickButton:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didCLickButton:(UIButton *)button{
[button removeFromSuperview];
}
相關(guān)代碼可以在我的github查看https://github.com/atony2099/ClassCluste