抽象工厂模式升级版————泛型化实现

引言

今天回看之前总结的抽象工厂模式的实现《Java常用设计模式————抽象工厂模式》,聚焦于抽象工厂模式的缺点,试着改进了一下。

回顾一下抽象工厂模式的缺点:

在添加新的产品类型时,难以扩展抽象工厂来生产新种类的产品。

这是怎么回事呢?原来,老套的实现方式是为每种类型的产品都创建一个具体的工厂类,这个类只生产一种特定类型的产品。因此,当有新的类型的产品加入系统时,就必须添加一个对应的工厂类来支持这类产品,不仅不利于扩展,而且会增加大量的工厂类。

例如之前会有如下两个具体产品的工厂类来生产对应类型的产品:

今天试着使用泛型的方式,得出了一种更加通用的抽象工厂实现方式。可以避免大量工厂的再造。

实现

为了本篇文章的完整性,依然将全部实现过程贴出,各位同学可以与《Java常用设计模式————抽象工厂模式》进行比较阅读。

一、抽象化产品族

产品族的概念其实很好理解,每种类型的产品就是一个产品族,它包含多种不同的表现形式,例如汽车就是一个产品族,它包含卡车、轿车等,这些具体的产品隶属于汽车这个产品族。

如图所示,创建了电视产品族和汽车产品族。电视产品族包括索尼电视夏普电视:

public interface Television {void play();
}
public class SonyTV implements Television{@Overridepublic void play() {System.out.println("SonyTV playing...");}
}
public class SharpTV implements Television{@Overridepublic void play() {System.out.println("SharpTV playing...");}
}

汽车产品族包括奥迪汽车奔驰汽车

public interface Car {void run();
}
public class Audi implements Car{@Overridepublic void run() {System.out.println("Audi running...");}
}
public class Benz implements Car{@Overridepublic void run() {System.out.println("Benz running...");}
}

二、创建抽象工厂及泛型工厂

抽象工厂是具体工厂的进一步抽象化,在原版的抽象工厂模式实现中,会存在多个具体的产品工厂,而在本例中,将会以泛型化的实现类来代替它们,而且即便再增加新的产品族也不需要修改泛型工厂:

public interface Factory<T> {T getProduct(Class<? extends T> clazz);
}
public class GenericFactory<T> implements Factory<T> {@Overridepublic T getProduct(Class<? extends T> clazz) {if (clazz == null)return null;try {T obj = (T) clazz.newInstance();return obj;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}
}

三、测试产品的生产

public class MyProgram {public static void main(String[] args) {Factory<Car> carFactory = new GenericFactory<>();Factory<Television> tvFactory = new GenericFactory<>();Car benz = carFactory.getProduct(Benz.class);Car audi = carFactory.getProduct(Audi.class);benz.run();audi.run();Television sonyTV = tvFactory.getProduct(SonyTV.class);Television sharpTV = tvFactory.getProduct(SharpTV.class);sonyTV.play();sharpTV.play();}
}

执行结果:

总结

抽象工厂是一种非常有趣的设计模式,它隔离了对象创建的过程,并且可以应用反射机制来完成这一经典的设计模式。但传统的实现需要具体每一个产品族的工厂,这样就依然没有提高通用性。本例中使用泛型的工厂方式,不需要为具体工厂的创建而增加新的编码。这种方式需要注意泛型的实现,使用<? extends T>可以完美的应对具体产品生产的需要。是一个非常不错的实现手段。

鸣谢

《Java常用设计模式————抽象工厂模式》

《Java泛型初探————泛型通配》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558926.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

发生在“注解”@的那些事儿

注解&#xff1a; 自定义注解&#xff1a; 注解和类&#xff0c;接口一样&#xff0c;属于一种数据类型 注解可以放在类&#xff0c;方法&#xff0c;属性上面 注解可以有属性&#xff0c;也可以没有属性 注解有作用范围 &#xff08; 源码期间&#xff08;String&#…

Java常用设计模式————建造者模式

引言 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单对象一步一步构建成一个复杂的对象。这种类型的设计模式属于建造型模式&#xff0c;它提供了一种创建对象的最佳方式。 一个Builder会一步步构建最终的对象。该Builder类是独立于其他对象的。 实现概要 …

使用动态代理解决网站字符集编码问题:(之前通过拦截器)

使用动态代理解决网站字符集编码问题&#xff1a;&#xff08;之前通过拦截器&#xff09; 设计模式&#xff1a; 在软件开发的过程中&#xff0c;遇到相识的问题&#xff0c;将问题的解决方式抽象为模型&#xff08;套路&#xff09; 单例模式&#xff08;静态代码只会执行一…

设计模式---简单工厂设计模式

先定义一个抽象类Animal&#xff1a; 定义两个动物类继承这个类&#xff1a; 定义一个专门生产动物的工程类&#xff1a; 最后定义一个测试类&#xff1a; 按照这个动物工厂类&#xff0c;你会发现&#xff0c;如果动物一多的话&#xff0c;就需要写很多重复的方法&#xff0c;…

Java 多线程 —— ThreadLocal

一、引言 ThreadLocal是Java帮助实现线程封闭性的典型手段。 作用&#xff1a;提供线程内的局部变量&#xff0c;这种变量在线程的生命周期内起作用&#xff0c;减少同一个线程内多个函数或组件之间一些公共变量的传递复杂度。同时也用来维护线程中的变量不被其他线程干扰。 …

设计模式---适配器设计模式

设计模式---适配器设计模式 什么事适配器&#xff1a; 1. 在使用监听的时候&#xff0c;需要定义一个类事件监听器接口 2. 通常接口中有多个方法&#xff0c;而程序中不一定所有的方法都用到&#xff0c;但又必须重写&#xff0c;很繁琐 3. 适配器简化了这些操作&#xff0c…

Java并发编程实战————售票问题

引言 现有一个需求如下&#xff1a; 有10000张火车票&#xff0c;每张票都有一个编号&#xff0c;同时有10个窗口对外售票&#xff0c;如何确保车票的正常售卖&#xff1f; 程序一&#xff1a;使用List 问题的解决办法都是从我们最最熟悉的角度思考。程序一&#xff0c;我们…

多线程相关知识

多线程相关知识 两个线程进行通信&#xff1a;通过等待&#xff08;wait&#xff09;唤醒&#xff08;notify&#xff09;机制 三个或三个以上线程进行通信&#xff1a;通过notifyAll&#xff08;&#xff09;方法 /* * 1. 在同步代码块中&#xff0c;用哪个对象锁&#xff0c…

Eclipse集成PyDev5.2.0开发插件

引言 在进行Python学习的时候&#xff0c;希望不使用IDLE进行开发&#xff0c;但是其他的IDE如PyCharm可能需要一段短暂时间的上手&#xff0c;因为开发过Java&#xff0c;所以使用能够集成到Eclipse上的PyDev插件进行开发应该会好一些。 但是在安装PyDev的时候发生了一些问题…

PostMan 四种常见的 POST 提交数据方式

HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。其中 POST 一般用来向服务端提交数据&#xff0c;本文主要讨论 POST 提交数据的几种方式。 协议规定 POST 提交的数据必须放在消息主体&#xff08;entity-body&#xff0…

史上最真实行业鄙视链

本文转载自菜鸟教程的微信公众号&#xff0c;原文链接&#xff1a;https://mp.weixin.qq.com/s/d9cdtq8y4Msq-_ZNof-iuw 引言 作为程序员的一份子&#xff0c;掌握好各个生态系统中的鄙视链&#xff0c;可以写出更加符合改变世界要求的代码。掌握了鄙视链&#xff0c;就掌握了…

权限验证框架Shiro

权限验证框架Shiro&#xff1a; Shiro简介 什么是Shiro&#xff1a; shiro是一个强大易用的Java安全框架&#xff0c;提供了认证&#xff0c;授权&#xff0c;加密&#xff0c;回话管理等功能&#xff1b; 认证&#xff08;Authentication&#xff09;&#xff1a;用户身份识别…

Mybatis从入门到精通上篇

Mybatis从入门到精通上篇&#xff1a; 学习过的持久层框架&#xff1a;DBUtils , Hibernate Mybatis就是类似于hibernate的orm持久层框架。 Mybatis介绍&#xff1a; Mybatis是面向sql的持久层框架&#xff0c;他封装了jdbc访问数据库的过程&#xff0c;我们开发&#xff0c;只…

Eclipse使用————Working Set工作集

引言 经常看到在设置项目的时候&#xff0c;如导入项目&#xff0c;新建项目等看到对话框的下方有一个“add to working set”复选框&#xff0c;为了弄清这个working set&#xff0c;我们就来好好了解一下Eclipse 的working set功能。 Working Set&#xff1f; Eclipse中通…

Mybatis从入门到精通下篇

Mybatis从入门到精通下篇&#xff1a; 输入类型&#xff1a; 输出类型&#xff1a; ResultMap&#xff1a; 动态sql&#xff1a; if标签&#xff1a; where标签&#xff1a; sql片段&#xff1a; foreach标签&#xff1a; 关联查询&#xff1a; 以订单作为主体&#xff1a; 一…

爱上进制转换练习

引言 对于可能接触到通讯行业或是物联网的开发工作者&#xff0c;一般会面对十进制、二进制、十六进制的转换工作&#xff0c;不仅仅是体现在代码上&#xff0c;有时候也需要用肉眼来进行快速的转化&#xff0c;以获取协议指令中的信息。 今天通过简单的整理&#xff0c;特此…

Sprint Boot————@Qualifier、@Primary

引言 使用Autowired自动注入时&#xff1a; 如果注入的接口有多个实现类&#xff0c;如下所示&#xff1a; 那么如果不指定具体是哪个实现类的Bean&#xff0c;在Spring Boot启动时就会发生异常&#xff08;下图请点击查看&#xff09;&#xff1a; 异常的描述信息非常简单&am…

SpringMVC教程上篇

SpringMVC教程上篇 SpringMVC优势&#xff1a; SpringMVC代码执行流程&#xff1a; 框架结构&#xff1a; 架构流程&#xff1a; 组件说明&#xff1a; SpringMVC与Mybatis整合 ! 效果: 开发流程&#xff1a;

Eclipse使用————生成Get/Set、toString快捷键(不使用鼠标)

引言 除了鼠标右键空白处—>source选择我们需要的操作之外是否还有更快捷的不需要鼠标的操作呢&#xff1f; 如何快速的通过键盘来生成get、set方法&#xff1f;如何快速的通过键盘生成toString方法&#xff1f;如何快速的通过键盘生成需要实现的父类方法呢&#xff1f; …

SpringMVC教程下篇

SpringMVC教程下篇 内容包括&#xff1a; 绑定数组&#xff1a; 将表单数据绑定到list&#xff1a; RequestMapping注解的三种用法&#xff1a; Controller方法返回值&#xff1a; 乱码问题总结 异常处理&#xff1a; 照片上传&#xff1a; RESTFUL支持&#xff…