简介:
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
举例:每个汽车4s店和某个品牌工厂之间的关系,每个汽车4s店只会卖同一品牌的汽车,但是如果这一品牌汽车销量不好,效益不佳,那么4s店可以更换进货的工厂,从而更换其售卖的品牌。
分析:每个品牌的汽车都有一个品牌工厂,这些工厂都有一个生产汽车的方法,4s店中应持有工厂的引用,所以这些汽车工厂都应该实现一个汽车工厂接口,这个4s店中持有汽车工厂的接口,以便更换汽车工厂改变品牌。
实现:
汽车工厂是用来生产汽车的,所以首先应该有一个汽车接口,所有汽车都有一个run方法
1 package com.mi.abstractfactory;
2
3 public interface Car {
4
5 void run();
6 }
实现这个接口创建一款汽车
package com.mi.abstractfactory;
/**
* 沃尔沃汽车
*/
public class VolvoCar implements Car{
@Override
public void run() {
System.out.println("沃尔沃:别赶路,去感受路!");
}
}
有了汽车类了,这样就可以使用工厂来批量生产了,创建一个汽车工厂接口,其中包含一个生产汽车的方法
1 package com.mi.abstractfactory;
2
3 /**
4 * 汽车工厂接口
5 * @author hellxz
6 */
7 public interface AbstractCarFactory {
8
9 //接口中所有的没有使用权限修饰符的方法,都是public static final的
10 Car getCar();
11 }
2.实现一个品牌汽车工厂
1 package com.mi.abstractfactory;
2 /**
3 * 沃尔沃汽车工厂
4 */
5 public class VolvoCarFactory implements AbstractCarFactory {
6
7 @Override
8 public VolvoCar getCar() {
9 return new VolvoCar();
10 }
11
12 }
3.创建一个汽车4s店,这个店铺需要有一个卖车的方法saleCar(),并持有一个工厂的引用
1 package com.mi.abstractfactory;
2
3 public class SSSS {
4
5 /**
6 * 实现抽象工厂对象的 注入有两种方式,一种是set设值注入,构造方法,都持有接口的引用
7 */
8 //持有引用,可以根据多态性,传入该接口的实现类型,从而实现不同的效果
9 private AbstractCarFactory carFactory;
10
11 public Car saleCar() {
12 return carFactory.getCar(); //抽象工厂获取方式得到car对象,可以是car的子类,多态
13 }
14
15 public void setCarFactory(AbstractCarFactory carFactory) {
16 this.carFactory = carFactory;
17 }
18
19 }
为了能看出来更换工厂的效果,同理创建一个Benz汽车的类和工厂
1 package com.mi.abstractfactory;
2
3 /**
4 * 奔驰汽车
5 * @author hellxz
6 */
7 public class BenzCar implements Car {
8
9 @Override
10 public void run() {
11 System.out.println("奔驰:随时准备好上路疾驶!");
12 }
13
14 }
1 package com.mi.abstractfactory;
2
3 /**
4 * 奔驰汽车工厂
5 * @author hellxz
6 */
7 public class BenzCarFactory implements AbstractCarFactory {
8
9 @Override
10 public BenzCar getCar() {
11 return new BenzCar();
12 }
13
14 // 也可以这样写,返回父类的引用,因为多态(动态绑定),在运行的时候会确定该类型 的具体类型
15 /* public Car getCar() {
16 * return new BenzCar();
17 * }
18 */
19
20 }
测试类
1 package com.mi.abstractfactory;
2
3 /**
4 * @author hellxz
5 */
6 public class Test {
7
8 public static void main(String[] args) {
9 SSSS ssss = new SSSS();
10 // ssss.setCarFactory(new BenzCarFactory()); //奔驰的工厂
11 ssss.setCarFactory(new VolvoCarFactory()); //沃尔沃的工厂
12 Car car = ssss.saleCar();
13 car.run();
14 }
15 }
输出:
沃尔沃:别赶路,去感受路!
测试更换工厂,打开注释行,注释掉沃尔沃的工厂行
输出:
奔驰:随时准备好上路疾驶!
总结:
主要解决:主要解决接口选择的问题。
何时使用:一个系统中有多个系列可选择的情况,每次只能选择其中一系列
优点:
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 降低耦合
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 接口 里加代码,又要在具体的里面加代码。
使用场景: 1、更换一整套的产品 2、生成不同操作系统的程序。