目录
一、定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
二、UML图
- AbstractFactory :抽象工厂角色,它声明了一组用于创建一种产品的方法,每一个方法对应一种产品,如上图中的 AbstractFactory 中就定义了两个方法,分别创建产品 A 和产品 B 。
- ConcreteFactory : 具体工厂角色,它实现了在抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中,如上述类图中的 ConcreteFactory1 、ConcreteFactory2。
- AbstractProduct: 抽象产品角色,它为每种产品声明接口,比如上述类图中的 AbstractProduct A, AbstractProduct B。
- ConcreteProduct: 具体产品角色,它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法,如上图的 ConcreteProductA1 , ConcreteProductA2 , ConcreteProductB1 ,ConcreteProductB2.
三、代码实现
说起抽象工厂不得不让人想起位于各大城市中鱼龙混杂的电子城。只有你想不到的,没有他们生产不出来的。 500块的Iphone你买到过吗?你见到过装有安卓系统、小米摄像头的苹果手机吗?下面让我们一起来见识一下装有安卓手机系统的苹果手机是怎么在电子城生产出来的。 手机卖家,也就是我们的手机工厂,使用主板、摄像头、手机外壳就能组装出一台手机。下面我们以代码为例:
1.抽象工厂
public interface IFactory {
//生产主板
MainBoard createMainBoard();
//生产摄像头
CameraLens createCameraLens();
//生产手机外壳
Case createCase();
}
2.具体工厂(分别组装了3种类型的手机)
/**
* 苹果手机
*/
public class AppleFactory implements IFactory {
@Override
public MainBoard createMainBoard() {
return new IosMainBoard();
}
@Override
public CameraLens createCameraLens() {
return new IosCameraLens();
}
@Override
public Case createCase() {
return new IosCase();
}
}
/**
* Android手机
*/
public class AndroidFactory implements IFactory {
@Override
public MainBoard createMainBoard() {
return new AndroidMainBoard();
}
@Override
public CameraLens createCameraLens() {
return new AndroidCameraLens();
}
@Override
public Case createCase() {
return new AndroidCase();
}
}
/**
* 装有安卓操作系统、安卓摄像头的苹果手机
*/
public class AndroidAppleFactory implements IFactory {
@Override
public MainBoard createMainBoard() {
return new AndroidMainBoard();
}
@Override
public CameraLens createCameraLens() {
return new AndroidCameraLens();
}
@Override
public Case createCase() {
return new IosCase();
}
}
3.抽象产品
/**
* 摄像头
*/
public interface CameraLens {
String getCameraLens();
}
/**
* 手机外壳
*/
public interface Case {
String getCase();
}
/**
* 主板
*/
public interface MainBoard {
String getMainBoard();
}
4.具体产品(不同的配件)
/**
* 安卓摄像头
*/
public class AndroidCameraLens implements CameraLens {
@Override
public String getCameraLens() {
return "安卓摄像头";
}
}
/**
* 安卓手机外壳
*/
public class AndroidCase implements Case {
@Override
public String getCase() {
return "安卓手机外壳";
}
}
/**
* 安卓主板
*/
public class AndroidMainBoard implements MainBoard {
@Override
public String getMainBoard() {
return "安卓主板";
}
}
/**
* 苹果摄像头
*/
public class IosCameraLens implements CameraLens {
@Override
public String getCameraLens() {
return "苹果摄像头";
}
}
/**
* 苹果手机外壳
*/
public class IosCase implements Case {
@Override
public String getCase() {
return "苹果手机外壳";
}
}
/**
* 苹果手机主板
*/
public class IosMainBoard implements MainBoard {
@Override
public String getMainBoard() {
return "苹果手机主板";
}
}
5.顾客买手机
(1)苹果手机
public class App {
public static void main(String[] args) {
IFactory factory = new AppleFactory();
String mainBoard = factory.createMainBoard().getMainBoard();
String cameraLens = factory.createCameraLens().getCameraLens();
String aCase = factory.createCase().getCase();
System.out.println(String.format("手机配件:%s、%s、%s,售价:12888", mainBoard, cameraLens, aCase));
}
}
手机配件:装有苹果主板、苹果摄像头、苹果手机外壳,售价:12888
(2)安卓手机
public class App {
public static void main(String[] args) {
IFactory factory = new AndroidFactory();
String mainBoard = factory.createMainBoard().getMainBoard();
String cameraLens = factory.createCameraLens().getCameraLens();
String aCase = factory.createCase().getCase();
System.out.println(String.format("手机配件:%s、%s、%s,售价:4000", mainBoard, cameraLens, aCase));
}
}
手机配件:装有安卓主板、安卓摄像头、安卓手机外壳,售价:4000
(3)装有安卓操作系统、安卓摄像头的苹果手机
public class App {
public static void main(String[] args) {
IFactory factory = new AndroidAppleFactory();
String mainBoard = factory.createMainBoard().getMainBoard();
String cameraLens = factory.createCameraLens().getCameraLens();
String aCase = factory.createCase().getCase();
System.out.println(String.format("手机配件:%s、%s、%s,售价:4000", mainBoard, cameraLens, aCase));
}
}
手机配件:安卓主板、安卓摄像头、苹果手机外壳,售价:500
四、总结
优点:
分离接口与实现,客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体实现是谁,客户端只是面向产品接口编程而已,使其从具体的产品实现中解耦,同时基于接口与实现的分离,使抽象工厂方法模式在切换产品类时更加灵活简单。
缺点:
随着产品类的增加,抽象工厂也得修改,相当于所有的具体工厂都得修改,不易扩展新的产品。
其实我们平时在开发中应该很少用到抽象工厂模式,一个很重要的原因是,其相对于其他两种工厂模式来说略显复杂,对于整体架构而言修改较大且不易扩展。
参考文件:
《大话设计模式》、《Head First》