美文网首页
iOS设计模式之工厂模式中(工厂方法)

iOS设计模式之工厂模式中(工厂方法)

作者: 点滴86 | 来源:发表于2024-04-23 22:42 被阅读0次

    工厂方法(Factory Method)

    将简单工厂方法中的if分支逻辑去掉,比较经典的处理方法是利用多态,重构之后如下:

    @protocol DMRuleConfigParserFactory <NSObject>
    
    - (id<DMRuleConfigParser>)createParser;
    
    @end
    
    @interface DMJsonRuleConfigParserFactory : NSObject <DMRuleConfigParserFactory>
    
    @end
    
    @implementation DMJsonRuleConfigParserFactory
    
    - (id<DMRuleConfigParser>)createParser
    {
        DMJsonRuleConfigParser *parser = [[DMJsonRuleConfigParser alloc] init];
        
        return parser;
    }
    
    @end
    
    @interface DMXmlRuleConfigParserFactory : NSObject <DMRuleConfigParserFactory>
    
    @end
    
    @implementation DMXmlRuleConfigParserFactory
    
    - (id<DMRuleConfigParser>)createParser
    {
        DMXmlRuleConfigParser *parser = [[DMXmlRuleConfigParser alloc] init];
        
        return parser;
    }
    
    @end
    
    @interface DMPropertiesRuleConfigParserFactory : NSObject <DMRuleConfigParserFactory>
    
    @end
    
    @implementation DMPropertiesRuleConfigParserFactory
    
    - (id<DMRuleConfigParser>)createParser
    {
        DMPropertiesRuleConfigParser *parser = [[DMPropertiesRuleConfigParser alloc] init];
        
        return parser;
    }
    
    @end
    

    这就是工厂方法模式的经典代码实现。当需要新增一种parser的时候,只需要新增一个实现了DMRuleConfigParserFactory协议的Factory类即可。所以,工厂模式比起简单工厂模式更加符合开闭原则。
    从上面的工厂方法的实现来看,一切都很完美,但是实际上存在挺大的问题。问题在于这些工厂类的使用上。接下来,看一下,如何使用这些工厂类来实现DMRuleConfigSource的factoryMethod方法。代码如下:

    @implementation DMRuleConfigSource
    
    - (void)factoryMethod
    {
        NSString *filePath = @"";
        NSString *fileExtension = [self getFileExtension:filePath];
        id<DMRuleConfigParserFactory> parserFactory = nil;
        if ([fileExtension isEqualToString:@"json"]) {
            parserFactory = [[DMJsonRuleConfigParserFactory alloc] init];
        } else if ([fileExtension isEqualToString:@"xml"]){
            parserFactory = [[DMXmlRuleConfigParserFactory alloc] init];
        } else if ([fileExtension isEqualToString:@"properties"]) {
            parserFactory = [[DMPropertiesRuleConfigParserFactory alloc] init];
        }
        
        id<DMRuleConfigParser> parser = [parserFactory createParser];
        NSString *fileContent = @"";
        // 从配置文件中读取配置文本到fileContent中
        DMRuleConfig *ruleConfig = [parser parse:fileContent];
    }
    
    
    /*
     *  根据文件路径获取文件后缀,比如demo.json返回json
     */
    - (NSString *)getFileExtension:(NSString *)filePath
    {
        return @"json";
    }
    
    @end
    

    从代码实现来看,工厂类对象的创建逻辑有耦合进了factoryMethod方法中,引入工厂方法非但没解决问题,反倒让设计变得更加复杂了,该怎么解决这个问题呢?可以为工厂类在创建一个简单工厂,也就是工厂的工厂,用来创建工厂类对象。DMRuleConfigParserFactoryMap类是创建工厂对象的工厂类,+ (id<DMRuleConfigParserFactory>)getParserFactory:(NSString *)configStr方法返回的是缓存好的单例工厂对象,如下:

    @interface DMRuleConfigParserFactoryMap : NSObject
    
    + (id<DMRuleConfigParserFactory>)getParserFactory:(NSString *)configStr;
    
    @end
    
    
    static NSMutableDictionary<NSString *, id<DMRuleConfigParserFactory>> *cachedFactories;
    
    @implementation DMRuleConfigParserFactoryMap
    
    + (void)load
    {
        cachedFactories = [[NSMutableDictionary<NSString *, id<DMRuleConfigParserFactory>> alloc] init];
        [cachedFactories setObject:[[DMJsonRuleConfigParserFactory alloc] init] forKey:@"json"];
        [cachedFactories setObject:[[DMXmlRuleConfigParserFactory alloc] init] forKey:@"xml"];
        [cachedFactories setObject:[[DMPropertiesRuleConfigParserFactory alloc] init] forKey:@"properties"];
    }
    
    + (id<DMRuleConfigParserFactory>)getParserFactory:(NSString *)configStr
    {
        return [cachedFactories objectForKey:configStr];
    }
    
    @end
    
    @implementation DMRuleConfigSource
    
    - (void)factoryMethod
    {
        NSString *filePath = @"";
        NSString *fileExtension = [self getFileExtension:filePath];
        id<DMRuleConfigParserFactory> parserFactory = [DMRuleConfigParserFactoryMap getParserFactory:fileExtension];
        
        id<DMRuleConfigParser> parser = [parserFactory createParser];
        NSString *fileContent = @"";
        // 从配置文件中读取配置文本到fileContent中
        DMRuleConfig *ruleConfig = [parser parse:fileContent];
    }
    
    /*
     *  根据文件路径获取文件后缀,比如demo.json返回json
     */
    - (NSString *)getFileExtension:(NSString *)filePath
    {
        return @"json";
    }
    
    @end
    
    

    当需要添加新的规则配置解析器的时候,只需要创建新的parser类和parserFactory类,并在DMRuleConfigParserFactoryMap类中,将新的parser factory对象添加到cachedFactories中即可。代码的改动非常少,基本上符合开闭原则。

    相关文章

      网友评论

          本文标题:iOS设计模式之工厂模式中(工厂方法)

          本文链接:https://www.haomeiwen.com/subject/swvwxjtx.html