抽象工厂模式
抽象工厂又叫做工厂的工厂。从某个角度来说抽象工厂是工厂方法模式的升级版。工厂方法模式相对简单,只负责某一类产品的创建工作,而工厂方法模式很强大,能创建很多的产品,从这个角度来说抽象工厂模式确实是工厂方法模式的升级。但是,从职能和应用场景上来看,不应该将抽象工厂看成是工厂方法模式的升级版。工厂方法模式通常运用在具有相同功能但是实现不同的产品类的创建,而抽象工厂模式则是运用于具备不同功能的产品族的创建。例如电脑厂商,通常一个电脑厂商既生产电脑也生产鼠标和键盘,如联想工厂生产联想的电脑,联想鼠标,联想键盘;华硕工厂生产华硕电脑、华硕鼠标和华硕键盘,而这些产品功能是不同的。且看下面代码实现:
package com.factory.abstractfactory;
public class Test {
public static void main(String[] args) {
ComputerFactory factory = new AsusComputerFactory();
// ComputerFactory factory = new LevonoComputerFactory();
Computer computer = factory.createComputer();
Mouse mouse = factory.createMouse();
Keyboard keyboard = factory.createKeyboard();
}
}
abstract class Mouse {
}
abstract class Computer {
}
abstract class Keyboard {
}
abstract class ComputerFactory {
public abstract Computer createComputer();
public abstract Mouse createMouse();
public abstract Keyboard createKeyboard();
}
class LevonoComputerFactory extends ComputerFactory {
public Computer createComputer() {
return new LevonoComputer();
}
public Mouse createMouse() {
return new LevonoMouse();
}
public Keyboard createKeyboard() {
return new LevonoKeyboard();
}
}
class AsusComputerFactory extends ComputerFactory {
public Computer createComputer() {
return new AsusComputer();
}
public Mouse createMouse() {
return new AsusMouse();
}
public Keyboard createKeyboard() {
return new AsusKeyboard();
}
}
class LevonoMouse extends Mouse {
}
class AsusMouse extends Mouse {
}
class LevonoComputer extends Computer {
}
class AsusComputer extends Computer {
}
class LevonoKeyboard extends Keyboard {
}
class AsusKeyboard extends Keyboard {
}
在上述代码中,比如说大家是在订购电脑设备,假如不想要华硕的,想要一整套联想的,只需要换工厂就可以了。这个跟很多网站上的换皮肤功能很像,换了皮肤主题,则包括皮肤、按钮布局等一整套都换掉。
抽象工厂的类图结构如下所示:
在图中,我们拥有Keyboard、Computer和Mouse三个产品族,每个产品族分别有联想和华硕两个牌子的产品;同时我们还拥有一个抽象工厂:ComputerFactory,其有两个子类LevonoComputerFactory和AsusComputerFactory,分别负责创建联想和华硕的键盘、电脑和鼠标。
抽象工厂模式的缺点
假设现在需求变更,不仅需要生产电脑、键盘和鼠标,还需要生产鼠标垫,那么就需要再扩展一个产品族:鼠标垫。相应的也就需要增加联想和华硕品牌的鼠标垫类,并修改抽象工厂类:ComputerFactory,进而LevonoComputerFactory和AsusComputerFactory也需要改变,违反了修改关闭原则。这也是抽象工厂模式最大的缺点:产品族扩展难。
抽象工厂模式优点
1.封装性,每个产品的实现类不是高层模块需要关心的,它仅仅关心接口,只需要知道工厂类是谁就能创建出需要的对象。
2.产品族内的约束为非公开状态。如生产一台电脑就有对应的一个键盘和一个鼠标。
抽象工厂模式使用场景
一个对象族(或者一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。如一个文本编辑器和一个图片编辑器,都是软件实体,但linux和windows下的文本编辑器和图片编辑器都是同样的功能和界面,但是实现的代码是不一样的,这就有了共同的约束条件:操作系统类型。于是就可以使用抽象工厂模式产生不同操作系统下的文本编辑器和图片编辑器。