定义:
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。)
凡是定义都比较抽象,光是看完定义介绍,不知道说了个啥,我们来翻译一下,意思是,客户端不必指定产品的具体类型,创建多个产品族中的产品对象。举个例子:
众所周知,手机厂商有苹果、小米、华为等。每个厂商都有手机、电脑等产品。
苹果有苹果手机、苹果电脑。小米有小米手机、小米电脑。把手机抽象出来,那么小米手机和苹果手机就是它的实现类,把电脑抽象出来,小米电脑和苹果电脑就是它的实现类。
抽象工厂UML类图:
我们以苹果、小米的手机、电脑为例,代码如下:
电脑族接口:
interface Computer {
void sayName();
}
小米电脑实现类:
public class XiaoMiComputer implements Computer {
@Override
public void sayName() {
System.out.println("我是小米电脑");
}
}
苹果电脑实现类:
public class AppleComputer implements Computer {
@Override
public void sayName() {
System.out.println("我是苹果电脑");
}
}
手机族接口:
interface Phone {
void sayName();
}
小米手机实现类:
public class XiaoMiPhone implements Phone{
@Override
public void sayName() {
System.out.println("我是小米手机");
}
}
苹果手机实现类:
public class ApplePhone implements Phone {
@Override
public void sayName() {
System.out.println("我是苹果手机");
}
}
抽象工厂:
interface Factory {
Phone createPhone();
Computer createComputer();
}
小米工厂实现类:
public class XiaoMiFactory implements Factory {
@Override
public Phone createPhone() {
return new XiaoMiPhone();
}
@Override
public Computer createComputer() {
return new XiaoMiComputer();
}
}
苹果工厂实现类:
public class AppleFactory implements Factory {
@Override
public Phone createPhone() {
return new ApplePhone();
}
@Override
public Computer createComputer() {
return new AppleComputer();
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
Factory xiaoMiFactory = new XiaoMiFactory();
xiaoMiFactory.createComputer().sayName();
xiaoMiFactory.createPhone().sayName();
Factory appleFactory = new AppleFactory();
appleFactory.createComputer().sayName();
appleFactory.createPhone().sayName();
}
}
结果:
我是小米电脑
我是小米手机
我是苹果电脑
我是苹果手机
优点:
封装性较好,每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来,这由工厂类负责,只要知道工厂类是谁,就能创建出一个需要的对象,省时省力。
缺点:
产品族扩展新的产品困难,需要修改抽象工厂接口。
增加了系统的抽象性和理解难度。