一、抽象工厂模式
1、生活场景
汽车生产根据用户选择的汽车类型,指定不同的工厂进行生产,选择红旗轿车,就要使用中国工厂,选择奥迪轿车,就要使用德国工厂。
2、抽象工厂模式
- 抽象工厂模式:定义了一个interface用于创建相关对象或相互依赖的对象,而无需指明具体的类;
- 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合;
- 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
- 将工厂抽象成两层,AbstractFactory(抽象工厂) 和 具体实现的工厂子类,方便程序扩展。
3、代码UML图

4、源代码实现
1/** 2 * 抽象工厂模式 3 */ 4public class C01_AbstractFactory { 5 public static void main(String[] args) { 6 CarProductFactory factory = new ChinaCarFactory() ; 7 factory.getCar("hq") ; 8 factory = new GermanyCarFactory () ; 9 factory.getCar("ad") ; 10 } 11} 12 13// 汽车生产抽象工厂 14interface CarProductFactory { 15 CarProduct getCar (String type) ; 16} 17// 中国汽车工厂 18class ChinaCarFactory implements CarProductFactory { 19 @Override 20 public CarProduct getCar(String type) { 21 CarProduct product = null ; 22 if ("hq".equals(type)){ 23 product = new HQCar() ; 24 product.name="红旗一号" ; 25 product.date="1999-09-19" ; 26 product.material(); 27 product.origin(); 28 } else if ("df".equals(type)){ 29 product = new DFCar() ; 30 product.name="东风一号" ; 31 product.date="2019-09-19" ; 32 product.material(); 33 product.origin(); 34 } 35 return product ; 36 } 37} 38// 德国汽车工厂 39class GermanyCarFactory implements CarProductFactory { 40 @Override 41 public CarProduct getCar(String type) { 42 CarProduct product = null ; 43 if ("ad".equals(type)){ 44 product = new ADCar() ; 45 product.name="奥迪A8" ; 46 product.date="2017-09-19" ; 47 product.material(); 48 product.origin(); 49 } else if ("bm".equals(type)){ 50 product = new BMCar() ; 51 product.name="宝马X8" ; 52 product.date="2018-09-19" ; 53 product.material(); 54 product.origin(); 55 } 56 return product ; 57 } 58} 59// 汽车生产抽象类 60abstract class CarProduct { 61 /** 62 * 汽车名称 63 */ 64 protected String name ; 65 /** 66 * 生产日期 67 */ 68 protected String date ; 69 /** 70 * 材料 71 */ 72 abstract void material () ; 73 /** 74 * 产地 75 */ 76 abstract void origin () ; 77} 78// 红旗车 79class HQCar extends CarProduct { 80 @Override 81 void material() { 82 System.out.println(super.name+"材料..."); 83 } 84 @Override 85 void origin() { 86 System.out.println(super.date+":"+super.name+"在中国北京生产"); 87 } 88} 89// 东风车 90class DFCar extends CarProduct { 91 @Override 92 void material() { 93 System.out.println(super.name+"材料..."); 94 } 95 @Override 96 void origin() { 97 System.out.println(super.date+":"+super.name+"在中国南京生产"); 98 } 99} 100// 奥迪车 101class ADCar extends CarProduct { 102 @Override 103 void material() { 104 System.out.println(super.name+"材料..."); 105 } 106 @Override 107 void origin() { 108 System.out.println(super.date+":"+super.name+"在德国柏林生产"); 109 } 110} 111// 宝马车 112class BMCar extends CarProduct { 113 @Override 114 void material() { 115 System.out.println(super.name+"材料..."); 116 } 117 @Override 118 void origin() { 119 System.out.println(super.date+":"+super.name+"在德国慕尼黑生产"); 120 } 121}
二、Spring框架应用
1、场景描述
Spring框架中获取配置文件中Bean的多种方式。
2、核心配置
1<bean id="carBean" class="com.model.design.spring.node04.abstractFactory.CarBean"> 2 <property name="name" value="中国红旗" /> 3</bean> 4<bean id="carBean1" class="com.model.design.spring.node04.abstractFactory.CarBean"> 5 <property name="name" value="德国奥迪" /> 6</bean>
3、测试文件
这里使用了两种方式获取。
1@RunWith(SpringJUnit4ClassRunner.class) 2@ContextConfiguration(locations = {"classpath:/spring/spring-abstract-factory.xml"}) 3public class SpringTest { 4 5 @Resource 6 private BeanFactory beanFactory ; 7 8 @Test 9 public void test01 (){ 10 CarBean carBean = (CarBean)beanFactory.getBean("carBean") ; 11 System.out.println(carBean.getName()); 12 } 13 14 @Test 15 public void test02 (){ 16 ApplicationContext context01 = new ClassPathXmlApplicationContext( 17 "/spring/spring-abstract-factory.xml"); 18 CarBean carBean = (CarBean)context01.getBean("carBean1") ; 19 System.out.println(carBean.getName()); 20 } 21}
4、结构分析

抽象工厂封装对象的创建。在Spring中,通过实现BeanFactory。可以从Spring的各种容器获取bean。根据Bean的配置,getBean方法可以返回不同类型的对象(单例作用域)或初始化新的对象(原型作用域)。在BeanFactory的实现中,我们可以区分:ClassPathXmlApplicationContext,XmlWebApplicationContext等。
三、工厂模式小结
三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式),工厂模式的核心用意将实例化对象的代码封装起来,放到工厂类中统一管理和维护,完成代码依赖关系的解耦。从而提高程序的可扩展性和维护性。
四、源代码地址
1GitHub地址:知了一笑 2https://github.com/cicadasmile/model-arithmetic-parent 3码云地址:知了一笑 4https://gitee.com/cicadasmile/model-arithmetic-parent
