23种设计模式-抽象工厂模式
1. 模式的定义
为创建一组相关或相互依赖的对象提供一个接口,而无需指定它们具体的类。
2. 使用场景
一个对象族或者一组没有任何关系的对象都有相同的约束,都可以使用抽象工厂模式(工厂方法模式是一个具体工厂创建一个类型的对象,抽象工厂模式是一个具体工厂创建一个产品族或者一系列的产品对象)。例如一个文本编辑器和一个图片处理器都是软件,但是Mac下的文本编辑器和 Windows 下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理软件也有类似情况。也就是具有了共同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图像浏览器。
3. UML类图
4. 角色介绍
- AbstractProduct: 抽象产品类
- ConcreteProductA : 产品的具体实现A
- ConcreteProductB : 产品的具体实现B
- AbstractFactory : 抽象工厂
- ConcreteFactory : 具体工厂实现
5. 简单示例
下面我们以上文中提到的文本编辑器和图像处理器来简单演示一下抽象工厂模式的使用。
/*** 抽象的Product, 文本编辑器抽象类* * @author mrsimple**/
public abstract class TextEditor { public abstract void edit(); public abstract void save();
} /*** 抽象产品类, 图像处理软件* * @author mrsimple**/
public abstract class ImageEditor { public abstract void edit(); public abstract void save();
} /*** MAC系统下文本编辑器的实现* @author mrsimple**/
public class MacTextEditor extends TextEditor { @Override public void edit() { System.out.println("文本编辑器,edit -- Mac版"); } @Override public void save() { System.out.println("文本编辑器, save -- Mac版"); } } /*** * MAC系统下图像编辑器的实现* @author mrsimple**/
public class MacImageEditor extends ImageEditor { @Override public void edit() { System.out.println("图片处理编辑器,edit -- Mac版"); } @Override public void save() { System.out.println("图片处理编辑器, save -- Mac版"); } } /*** 应用软件抽象工厂* classes.* * @author mrsimple**/
public abstract class AppFactory { public abstract TextEditor createTextEditor(); public abstract ImageEditor createImageEditor();
} /*** 具体工厂, 创建各种应用, 这里为文本编辑器和图像编辑器.* * @author mrsimple**/
public class MacAppFactory extends AppFactory { @Override public TextEditor createTextEditor() { return new MacTextEditor(); } @Override public ImageEditor createImageEditor() { return new MacImageEditor(); } }
上面的示例中给出了文本处理器和图像处理器的MAC版实现,AppFactory中定义了创建文本编辑器和图像编辑器的函数( 创建应用软件这一类的产品族 ),并在MacAppFactory具体实现,创建Mac下实现的两种编辑器。同样,我们可以实现Windows下的两种编辑器的实现,然后再实现一个Windows下的App工厂,通过该工厂返回windows下的编辑器的具体实现的对象。这样,我们就可以通过工厂提供的接口创建整个产品族的对象。
AppFactory factory = new MacAppFactory();
TextEditor textEditor = factory.createTextEditor();
textEditor.edit();
textEditor.save(); ImageEditor imageEditor = factory.createImageEditor();
imageEditor.edit();
imageEditor.save();
6. 优点与缺点
优点 :
- 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建;
- 容易改变产品的系列;
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
- 将一个系列的产品族统一到一起创建,客户代码易于使用。
缺点 :
抽象工厂模式的最大缺点就是产品族扩展非常困难,为什么这么说呢?我们以通用代码为例,如果要增加一个产品 C, 也就是说产品家族由原来的 2 个增加到 3 个,看看我们的程序有多大改动吧!抽象类 AbstractCreator 要增加一个方法 createProductC(), 然后两个实现类都要修改,想想看,这严重违反了开闭原则,而且我们一直说明抽象类和接口是一个契约。