抽象工厂模式,即Abstract Factory Pattern,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。
抽象工厂模式与工厂方法模式最大的区别:抽象工厂中每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类。
抽象工厂模式的角色与工厂方法模式一样,有如下几种:
2.1 抽象产品(Product):
工厂方法模式所创建的对象的超类,也就是所有产品类的共同父类或共同拥有的接口。在实际的系统中,这个角色也常常使用抽象类实现。
2.2 具体产品(ConcreteProduct):
这个角色实现了抽象产品(Product)所声明的接口,工厂方法模式所创建的每一个对象都是某个具体产品的实例。
2.3 抽象工厂(Factory):
担任这个角色的是工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类实现。
2.4 具体工厂(ConcreteFactory):
担任这个角色的是实现了抽象工厂接口的具体Java类。具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建具体产品对象。
实例模型:我们都知道富士康是手机代工厂,既能生产小米手机,也能生产苹果手机。冠捷是全球有名的电视代工厂,既然生产飞利浦电视,也能生产夏普的电视。
抽象产品接口:
手机抽象类:
package zzw.cn.factory.abstractfactory;
/**
* 手机抽象类
*/
public interface IPhone
{
void call();
}
电视抽象类:
package zzw.cn.factory.abstractfactory;
/**
* 电视抽象类
*/
public interface ITV
{
void show();
}
抽象工厂类:
手机工厂抽象类:
package zzw.cn.factory.abstractfactory;
/**
* 抽象工厂类:抽象手机工厂类,负责生产小米手机和苹果手机
*/
public interface IPhoneFactory
{
IPhone produceMiPhone();
IPhone produceApplePhone();
}
电视工厂抽象类:
package zzw.cn.factory.abstractfactory;
/**
* 电视生产工厂的接口
*/
public interface ITVFactory
{
ITV producePhilipsTV();//生产飞利浦电视
ITV produceSharpTV();//生产夏普电视
}
具体工厂类:
富士康负责生产具体手机的工厂:
package zzw.cn.factory.abstractfactory;
/**
* 具体工厂类:富士康手机工厂,负责生产小米和苹果手机
*/
public class FoxconnFactory implements IPhoneFactory
{
@Override
public IPhone produceMiPhone()
{
return new MiPhone();
}
@Override
public IPhone produceApplePhone()
{
return new ApplePhone();
}
}
冠捷负责生产具体电视的工厂:
package zzw.cn.factory.abstractfactory;
/**
* 电视生产工厂类:冠捷电视长,负责生产飞利浦和夏普电视
*/
public class TPVFactory implements ITVFactory
{
@Override
public ITV producePhilipsTV()
{
return new PhilipsTV();
}
@Override
public ITV produceSharpTV()
{
return new SharpTV();
}
}
测试类:
创建出富士康工厂对象,通过富士康工厂生产小米手机和苹果手机,并用手机拨打电话。创建出冠捷工厂对象,通过冠捷生产飞利浦电视和夏普电视,并使用电视。
package zzw.cn.factory.abstractfactory;
public class TestAbstractFactory
{
public static void main(String[] args)
{
IPhoneFactory phoneFactory = new FoxconnFactory();
IPhone applePhone = phoneFactory.produceApplePhone();
applePhone.call();
IPhone miPhone = phoneFactory.produceMiPhone();
miPhone.call();
ITVFactory tvFactory = new TPVFactory();
ITV philipsTV = tvFactory.producePhilipsTV();
philipsTV.show();
ITV sharpTV = tvFactory.produceSharpTV();
sharpTV.show();
}
}
结果:
I am a Apple Phone.
I am a MI Phone.
I am a Philips TV.
I am a SHARP TV.
Process finished with exit code 0
优点:
a. 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
b. 增加新的具体工厂和产品族很方便,因为一个具体的工厂实现代表的是一个产品族,无须修改已有系统,符合“开闭原则”。
缺点:
a. 在添加新的产品对象(不同于现有的产品等级结构)时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
b. 增加新的工厂和产品族容易,增加新的产品等级结构麻烦。