设计模式——抽象工厂模式

170 阅读3分钟

一、概述

抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个产品,而抽象工厂模式可生产多个产品。

使用抽象工厂模式一般要满足以下条件:

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

抽象工厂模式同工厂方法模式一样,也是由【抽象工厂】、【具体工厂】、【抽象产品】、【具体产品】这4个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。下面就以创建手机和平板工厂为例。

二、使用

先来看第一个产品手机phone部分,定义了通用抽象接口来展示手机名称。

public interface PhoneInterface {
    String getName();
}

其次是定义了具体的手机产品,小米和华为分别继承自PhoneInterface。

public class HuaWeiPhone implements PhoneInterface{
    @Override
    public String getName() {
        return "华为手机";
    }
}
public class XiaoMiPhone implements PhoneInterface{
    @Override
    public String getName() {
        return "小米手机";
    }
}

接下来是第二个产品平板pad部分,也是和phone是大同小异的。

public interface PadInterface {
    String getName();
}

其次是定义了具体的平板产品,微软的surface和苹果的ipad。

public class SurfacePad implements PadInterface{
    @Override
    public String getName() {
        return "微软surface";
    }
}
public class ApplePad implements PadInterface{
    @Override
    public String getName() {
        return "苹果iPad";
    }
}

产品定义完之后,然后就是最重要的部分——工厂。我们先定义工厂通用的抽象。

public abstract class AbstractFactoryInterface {
    public abstract PhoneInterface getPhone();
    public abstract PadInterface getPad();
}

再来定义具体的工厂,用来生产具体的产品。我们这里定义了2个产品族,第一个产品族用来生产华为手机和苹果pad;第二个产品族用来生产小米手机和微软surface。

public class ProductFactory1 extends AbstractFactoryInterface {

    @Override
    public PhoneInterface getPhone() {
        return new HuaWeiPhone();
    }

    @Override
    public PadInterface getPad() {
        return new ApplePad();
    }
}
public class ProductFactory2 extends AbstractFactoryInterface{

    @Override
    public PhoneInterface getPhone() {
        return new XiaoMiPhone();
    }

    @Override
    public PadInterface getPad() {
        return new SurfacePad();
    }
}

最后我们可以根据需要来生产产品1还是产品2,这里定义一个用于生成工厂的类,根据传入的类型来生产。定义此类也是为了方便以后能够扩展,比如生产产品3....等等,可以进行统一管理。

public class MyFactory {
    public static AbstractFactoryInterface getFactory(String factoryName) {
        if (AbstractFactoryActivity.FactoryType1.equalsIgnoreCase(factoryName)) {
            return new ProductFactory1();
        } else {
            return new ProductFactory2();
        }
    }
}

最后进行测试。

public static final String FactoryType1 = "FactoryType1";
public static final String FactoryType2 = "FactoryType2";

AbstractFactoryInterface factoryInterface1 = MyFactory.getFactory(FactoryType1);
PhoneInterface huaweiPhoneInterface = factoryInterface1.getPhone();
PadInterface applePadInterface = factoryInterface1.getPad();
Log.e(TAG, "huaweiPhoneInterface:" + huaweiPhoneInterface.getName());
Log.e(TAG, "applePadInterface:" + applePadInterface.getName());

Log.e(TAG, "-------------------------------");

AbstractFactoryInterface factoryInterface2 = MyFactory.getFactory(FactoryType2);
PhoneInterface xiaomiPhoneInterface = factoryInterface2.getPhone();
PadInterface surfacePadInterface = factoryInterface2.getPad();
Log.e(TAG, "xiaomiPhoneInterface:" + xiaomiPhoneInterface.getName());
Log.e(TAG, "surfacePadInterface:" + surfacePadInterface.getName());

运行程序得到以下输出。

三、总结

从上面的代码中,如果我们想要添加新的产品族,直接新建产品类和工厂,无需修改通用接口,这样就不会破坏开闭原则,和工厂方法一样,分离接口与实现,用户根本不知道具体的实现是谁。当然缺点也是很显然的,类的数量很增加很多。

github地址:github.com/leewell5717…

四、参考

设计模式之抽象工厂模式(Java实现)

JAVA设计模式-抽象工厂模式