Spiga

模式开发之旅(7):抽象工厂模式

2010-07-01 12:19:39

抽象工厂模式的应用场景比较特殊,没有前两种常用。

在简单工厂和工厂方法中,类只有一种分类方式。比如,在规则配置解析那个例子中,解析器类只会根据配置文件格式(Json、Xml、Yaml……)来分类。但是,如果类有两种分类方式,比如,我们既可以按照配置文件格式来分类,也可以按照解析的对象(Rule 规则配置还是 System 系统配置)来分类,那就会对应下面这 6 个 parser 类。

针对规则配置的解析器:基于接口IRuleConfigParser
JsonRuleConfigParser
XmlRuleConfigParser
YamlRuleConfigParser
针对系统配置的解析器:基于接口ISystemConfigParser
JsonSystemConfigParser
XmlSystemConfigParser
YamlSystemConfigParser

针对这种特殊的场景,如果还是继续用工厂方法来实现的话,我们要针对每个 parser 都编写一个工厂类,也就是要编写 6 个工厂类。如果我们未来还需要增加针对业务配置的解析器(比如 IBizConfigParser),那就要再对应地增加 3 个工厂类。而我们知道,过多的类也会让系统难维护。这个问题该怎么解决呢?

抽象工厂就是针对这种非常特殊的场景而诞生的。我们可以让一个工厂负责创建多个不同类型的对象(IRuleConfigParser、ISystemConfigParser 等),而不是只创建一种 parser 对象。这样就可以有效地减少工厂类的个数。具体的代码实现如下所示:

public interface IConfigParserFactory
{
    IRuleConfigParser CreateRuleParser(); 
    ISystemConfigParser CreateSystemParser(); 
    //此处可以扩展新的parser类型,比如IBizConfigParser
}

public class JsonRuleConfigParserFactory : IConfigParserFactory
{ 
    public override IRuleConfigParser CreateRuleParser() {
        return new JsonRuleConfigParser();
    }

    public override ISystemConfigParser CreateSystemParser()
    {
        return new JsonSystemConfigParser();
    }
}

public class XmlRuleConfigParserFactory : IConfigParserFactory
{
    public override IRuleConfigParser CreateRuleParser()
    {
        return new XmlRuleConfigParser();
    }

    public override ISystemConfigParser CreateSystemParser()
    {
        return new XmlSystemConfigParser();
    }
}

public class YamlRuleConfigParserFactory : IConfigParserFactory
{
    public override IRuleConfigParser CreateRuleParser()
    {
        return new YamlRuleConfigParser();
    }

    public override ISystemConfigParser CreateSystemParser()
    {
        return new YamlSystemConfigParser();
    }
}

最后看一下抽象工厂的描述与结构图:

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。