本文源码:GitHub·点这里 || GitEE·点这里

一、抽象工厂模式

1、生活场景

汽车生产根据用户选择的汽车类型,指定不同的工厂进行生产,选择红旗轿车,就要使用中国工厂,选择奥迪轿车,就要使用德国工厂。

2、抽象工厂模式

  1. 抽象工厂模式:定义了一个interface用于创建相关对象或相互依赖的对象,而无需指明具体的类;
  2. 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合;
  3. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
  4. 将工厂抽象成两层,AbstractFactory(抽象工厂) 和 具体实现的工厂子类,方便程序扩展。

3、代码UML图

4、源代码实现

/**
* 抽象工厂模式
*/
public class C01_AbstractFactory {
public static void main(String[] args) {
CarProductFactory factory = new ChinaCarFactory() ;
factory.getCar("hq") ;
factory = new GermanyCarFactory () ;
factory.getCar("ad") ;
}
} // 汽车生产抽象工厂
interface CarProductFactory {
CarProduct getCar (String type) ;
}
// 中国汽车工厂
class ChinaCarFactory implements CarProductFactory {
@Override
public CarProduct getCar(String type) {
CarProduct product = null ;
if ("hq".equals(type)){
product = new HQCar() ;
product.name="红旗一号" ;
product.date="1999-09-19" ;
product.material();
product.origin();
} else if ("df".equals(type)){
product = new DFCar() ;
product.name="东风一号" ;
product.date="2019-09-19" ;
product.material();
product.origin();
}
return product ;
}
}
// 德国汽车工厂
class GermanyCarFactory implements CarProductFactory {
@Override
public CarProduct getCar(String type) {
CarProduct product = null ;
if ("ad".equals(type)){
product = new ADCar() ;
product.name="奥迪A8" ;
product.date="2017-09-19" ;
product.material();
product.origin();
} else if ("bm".equals(type)){
product = new BMCar() ;
product.name="宝马X8" ;
product.date="2018-09-19" ;
product.material();
product.origin();
}
return product ;
}
}
// 汽车生产抽象类
abstract class CarProduct {
/**
* 汽车名称
*/
protected String name ;
/**
* 生产日期
*/
protected String date ;
/**
* 材料
*/
abstract void material () ;
/**
* 产地
*/
abstract void origin () ;
}
// 红旗车
class HQCar extends CarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.date+":"+super.name+"在中国北京生产");
}
}
// 东风车
class DFCar extends CarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.date+":"+super.name+"在中国南京生产");
}
}
// 奥迪车
class ADCar extends CarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.date+":"+super.name+"在德国柏林生产");
}
}
// 宝马车
class BMCar extends CarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.date+":"+super.name+"在德国慕尼黑生产");
}
}

二、Spring框架应用

1、场景描述

Spring框架中获取配置文件中Bean的多种方式。

2、核心配置

<bean id="carBean" class="com.model.design.spring.node04.abstractFactory.CarBean">
<property name="name" value="中国红旗" />
</bean>
<bean id="carBean1" class="com.model.design.spring.node04.abstractFactory.CarBean">
<property name="name" value="德国奥迪" />
</bean>

3、测试文件

这里使用了两种方式获取。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/spring/spring-abstract-factory.xml"})
public class SpringTest { @Resource
private BeanFactory beanFactory ; @Test
public void test01 (){
CarBean carBean = (CarBean)beanFactory.getBean("carBean") ;
System.out.println(carBean.getName());
} @Test
public void test02 (){
ApplicationContext context01 = new ClassPathXmlApplicationContext(
"/spring/spring-abstract-factory.xml");
CarBean carBean = (CarBean)context01.getBean("carBean1") ;
System.out.println(carBean.getName());
}
}

4、结构分析



抽象工厂封装对象的创建。在Spring中,通过实现BeanFactory。可以从Spring的各种容器获取bean。根据Bean的配置,getBean方法可以返回不同类型的对象(单例作用域)或初始化新的对象(原型作用域)。在BeanFactory的实现中,我们可以区分:ClassPathXmlApplicationContext,XmlWebApplicationContext等。

三、工厂模式小结

三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式),工厂模式的核心用意将实例化对象的代码封装起来,放到工厂类中统一管理和维护,完成代码依赖关系的解耦。从而提高程序的可扩展性和维护性。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

最新文章

  1. sql server之ROW_NUMBER() OVER()取每组的第N行数据
  2. EventBus使用详解(一)
  3. 30分钟LINQ教程(转)
  4. 关于变量在for循环内外定义的思考
  5. android 数据库的增删改查的另一种方式
  6. Android 给ListView设置Adapter
  7. Swift—属性观察者-备
  8. android 签名被篡改(Keystore was tampered with, or password was incorrect)
  9. Linux Mysql Client 查询中文乱码
  10. 聊聊keep-alive组件的使用及其实现原理
  11. Spring Boot快速入门(一): Hello Spring Boot
  12. JVM学习--(二)内存模型、可见性、指令重排序
  13. RubyGems系列之RubyGems初识
  14. 勾勾街:一个专业的苹果ios app 自助打包的网站,免越狱,免证书签名
  15. 提升SQLite数据插入效率低、速度慢的方法
  16. k8s 英文文档翻译
  17. Wordpress“固定链接”页面出现404原因及解决方法
  18. 在windows下搭建vueJS开发环境
  19. 27.反射2.md
  20. linux 比较两个文件夹不同 (diff命令, md5列表)

热门文章

  1. tabhost改变标签颜色
  2. 在C#中将对象序列化成Json格式
  3. Error: Cannot find module &#39;webpack/lib/node/NodeTemplatePlugin&#39;
  4. PDF提取表格的网页工具——Excalibur
  5. 【并发编程】Java并发编程传送门
  6. 前后端分离crud(跨域问题)讲解
  7. Cesium专栏-地形开挖2-任意多边形开挖(附源码下载)
  8. mysql中msvcr120.dll文件丢失问题
  9. windows 安装xps查看器; windows 10 安装 xps viewer
  10. mysql如何处理高并发(转)