設計模式——工廠模式之簡單工廠

我們常見的設計模式,大致可以分爲三大類:創建型、結構性、行爲型。工廠模式,屬於創建型。


工廠模式到底起的是什麼作用呢?概括來說就是解耦。當某一類對象需要頻繁創建的時候,就會和程序產生比較大的耦合,在對象初始化屬性較多時,工廠模式可以較少這種耦合,這就是他的作用。


一般情況下根據場景不同,工廠模式有幾種不同的形式,簡單工廠、工廠方法和抽象工廠,可以說這三種的關係是層層遞進的。今天我們就說簡單工廠。

首先可以創建RCButtonRCImageView兩個自定義的類用來測試,接下來就就是工廠類的實現

viewFactory.m

@implementation ViewFactory
+(NSObject*)creatViews{
    return [[RCButton alloc] init];
}
@end

這樣我們就可以直接調用工廠類的類方法來創建對象了

RCButton *button = [ViewFactory creatViews];

這樣寫完就是一個簡單工廠了,但其實我們並不會這樣寫,因爲一個工廠通常要製造出不同類型的對象,就像一個服裝廠,既可以聲場衣服,又可以生產寫字鞋子,還可以生產帽子等等,其實在工廠類的.m中要這樣寫

+(NSObject*)creatViews:(NSInteger)chose{
    NSObject* obj = nil;
    switch (chose) {
        case 1:
            obj = [[RCButton alloc] init];
            break;
        case 2:
            obj = [[RCImageView alloc] init];
            break;
        default:
            obj = [[RCButton02 alloc] init];
            break;
    }
    return obj;
}

這樣我們就可以通過傳入相應的chose來創建我們想要的對象了

RCButton *button = [ViewFactory creatViews:0];
RCImageView *imageView = [ViewFactory creatViews:1];

這樣寫其實還存在一些問題,如果說只有兩三個類型的對象,這種方式就可以滿足了,但如果我們的對象類型很多呢,50個類型要寫50個判斷嗎,有沒有設麼方式可以不去做類型的判斷呢,當然是有的,這個時候,我們一般是把工廠對象設置成單例,然後這樣做

viewFactory.m

static ViewFactory *instance = nil;
+ (id)sharedInstance{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        instance = [[ViewFactory alloc]init];
    });
    return instance;
}
- (instancetype)init{
    self = [super init];
    if (self) {
        _dic = [[NSMutableDictionary alloc] init];
        [_dic setObject:@"RCButton" forKey:@"1"];
        [_dic setObject:@"RCImageView" forKey:@"2"];
        [_dic setObject:@"RCImageView02" forKey:@"3"];
    }
    return self;
}
-(NSObject*)creatViews:(NSInteger)chose{
    NSString* name = [NSString stringWithFormat:@"%ld",(long)chose];
    return [[NSClassFromString([_dic objectForKey:name]) alloc] init];
}

在工廠類裏面配置好每個key對應的類型,創建對象的時候,直接傳入一個key,就能得到我們想要的對象了,是不是很方便,這樣即使是有100個類型,我們只需要在工廠裏面配置下存儲對象類型的_dic就搞定了


寫到這裏其實已經很完善了,唯一的不足是對象類型的配置,有更好的方式,那就是通過配置文件去動態的加載對象類型,而不是寫在工廠類裏面。也就是將配置信息放到配置文件中,通過解析配置文件,得到存儲對象類型的_dic


 配置文件裏的內容是這樣的

<?xml version="1.0" encoding="UTF-8"?>
<views>
    <view key="1" className="RCButton05"/>
    <view key="2" className="RCImageView02"/>
    <view key="3" className="RCImageView03"/>
    <view key="4" className="RCImageView04"/>
    <view key="5" className="RCImageView05"/>
    <view key="6" className="RCImageView06"/>
    <view key="7" className="RCImageView07"/>
    <view key="8" className="RCImageView08"/>
</views>

遵循NSXMLParserDelegate之後,解析的過程是這樣的

-(NSMutableDictionary*)parser{
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    NSString*path = [[NSBundle mainBundle] pathForResource:@"ViewFactoryConfig" ofType:@"xml"];
    NSURL* url = [[NSURL alloc] initFileURLWithPath:path];
    NSXMLParser *parser=[[NSXMLParser alloc] initWithContentsOfURL:url];
    parser.delegate = self;
    [parser parse];
    return dic;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict{
    _currentElementName = elementName;
    if ([elementName isEqualToString:@"view"]) {
        NSString* key = [attributeDict objectForKey:@"key"];
        NSString* className = [attributeDict objectForKey:@"className"];
        [_dic setObject:className forKey:key];
    }
}

這樣就拿到了存儲配置信息的_dic,只需在初始化工廠類的時候,執行這個解析的操作,其餘步驟都不用做修改,這樣,一個完整的簡單工廠就實現了,不管是多少個類,我們都不需要去改動的什麼代碼,只需修改配置文件,傳入對應的key,我們就能創建出想要的對象了。


工廠模式中工廠方法的使用http://blog.csdn.net/neveraway1993/article/details/72966001


希望對你有幫助!






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章