抽象工厂模式

定义一个抽象工厂,然后实现若干个子类工厂,用于实例化不同的产品子类对象。

abstract class Factory
{
    public ProductA CreateProductA();

    public ProductB CreateProductB();
}

class Factory1 : Factory
{
    override public ProductA CreateProductA()
    {
        return new ProductA1();
    }

    override public ProductB CreateProductB()
    {
        return new ProductB1();
    }
}

class Factory2 : Factory
{
    override public ProductA CreateProductA()
    {
        return new ProductA2();
    }

    override public ProductB CreateProductB()
    {
        return new ProductB2();
    }
}

调用

Factory factory1 = new Factory1();
ProductA = factory1.CreateProductA();
ProductB = factory1.CreateProductB(); 
Factory factory2 = new Factory();
ProductA = factory2.CreateProductA();
ProductB = factory2.CreateProductB();

优点

  • 现有产品的子类产品扩展方便
    比如,ProductA衍生出新的子类产品ProductA3。则只需要扩展一个新的工厂Factory3即可,不需要修改原有的工厂类。

缺点

  • 新类型的产品无法扩展,只能修改原有代码
    比如新添加一个产品,ProductC。首先需要在抽象工厂Factory中添加接口:
public ProductC CreateProductC();

还要在所有工厂子类中实现这个接口。违背了“开闭原则”。

举例

  • 如果想要封装不同数据库的差异,首先定义了一个抽象数据库工厂类DateBaseFactory,然后定义了基本的接口。之后继承此抽象工厂,实现了不同类型的数据库工厂,DataBaseFactoryMySQL, DataBaseFactoryMongo。

  • 如果现在要支持SQLServer,则非常方便,新添加一个DataBaseFactorySQLServer即可。

  • 但此时要对数据库添加新的操作,则要修改每一个类,添加相对的接口。

改进

  • 从调用具体工厂的代码可以看出,调用者虽然没有与具体的产品类耦合,但却与具体的工厂类耦合了。为了解决这个问题,我们可以使用配置文件,记录要使用的工厂类字符串,然后在代码中使用反射动态创建工厂对象,从而让调用者也与具体的工厂类解藕。

  • 毕竟,修改配置文件,要比修改代码方便的多。

你可能感兴趣的:(抽象工厂模式)