抽象工厂模式
定义
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类
可以把此类工厂比做一个有多个生产线的车间,生产线产出的产品有相似的约束或者依赖的关系,
比如:我要生产汽车就需要同时生产汽车对应型号的钥匙
uml
优点
· 封装性
高层模块不关心产品的实现,只关心抽象,接口,
具体的工厂类负责创建对象,而不必知道内部产品的关联,以及依赖关系的实现,只需要知道工厂类即可生成一个对象
· 产品族内的约束为非公开状态
对封装性的一个补充,封装内部约束,避免每次高层调用时都去理解内部约束的实现,也是对内部对内部约束的一个保护
· 横向扩展容易
在上面UML的基础上我需要增加一个3系列,只需要能加3系列的产品A-3和产品B-3,并增加产品3系列的工厂Product3Factory即可完成扩展
缺点
· 产品族的扩展非常困难,即垂直扩展困难,比如说在上面UML的实现的基础上增加一个额外的产品C,我就需要修改AbstractFactory以及所有它的实现,这完全不符合开闭原则。
使用场景
一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式
实现
- Bmw汽车和汽车钥匙 都受汽车系列约束
public abstract class AbstractBmwXCar {
public abstract void getPrice();
}
public abstract class AbstractBwmXCarKey {
public abstract void openCar() ;
}
- 产品实现
public class BwmX5 extends AbstractBmwXCar {
@Override
public void getPrice() {
System.out.println("我是X5 我要150W");
}
}
public class BwmX6 extends AbstractBmwXCar {
@Override
public void getPrice() {
System.out.println("我是X6,我要180W");
}
}
public class X5KeyBwmX extends AbstractBwmXCarKey {
@Override
public void openCar() {
System.out.println("我能打开X5的车门");
}
}
public class X6KeyBwmX extends AbstractBwmXCarKey {
@Override
public void openCar() {
System.out.println("我能打开X6的车门");
}
}
- 抽象工厂
public abstract class AbstractCarFactory {
public abstract AbstractBmwXCar createCar();
public abstract AbstractBwmXCarKey createKey();
}
- 工厂实现
public class X5Factory extends AbstractCarFactory {
@Override
public BwmX5 createCar() {
BwmX5 bwmX5 = new BwmX5();
return bwmX5;
}
@Override
public X5KeyBwmX createKey() {
X5KeyBwmX x5Key = new X5KeyBwmX();
return x5Key;
}
}
public class X6Factory extends AbstractCarFactory {
@Override
public BwmX6 createCar() {
BwmX6 bwmX6 = new BwmX6();
return bwmX6;
}
@Override
public X6KeyBwmX createKey() {
X6KeyBwmX x6Key = new X6KeyBwmX();
return x6Key;
}
}
- 客户端调用
public class BmwCeo {
public static void main(String[] args) {
X5Factory x5Factory = new X5Factory();
X6Factory x6Factory = new X6Factory();
BwmX5 x5_1 = x5Factory.createCar();
X5KeyBwmX x5Key = x5Factory.createKey();
BwmX6 x6_1 = x6Factory.createCar();
X6KeyBwmX x6Key = x6Factory.createKey();
// 下面可以做自己的处理了
}
}