【AICon】 如何构建高效的 RAG 系统?RAG 技术在实际应用中遇到的挑战及应对策略?>>> 了解详情
写点什么

AutoMapper 及静态类之争论

  • 2016-03-16
  • 本文字数:1513 字

    阅读完需:约 5 分钟

在进行 API 设计时,静态类的使用有时会为设计者带来一些烦恼。应该将某个函数暴露为静态函数还是实例方法,这一点常常会造成人们的争论。

静态函数的主要优点在于其简便性。调用者可以在代码中的任意位置使用静态函数,而无需为实例的创建、管理以及依赖注入等问题而烦恼。并且由于没有创建新的实例,因而也不存在垃圾回收的问题,从而使性能也得以提高。

如果没有维护状态的需求,以上的论点确实是成立的。如若不然,则设计者必须保证静态函数的线程安全,而这往往牵涉到开销较大的加锁与同步等技术。而且即便独立的调用是线程安全的,但调用者也往往需要将一系列调用过程封装为一个原子性的事务。AutoMapper 目前也遇到了这方面的麻烦。

AutoMapper 最初是围绕着静态函数而设计的,但随着时间的推移,它的可配置性也在逐步提高。每当出现新的配置选项,就需要管理更多的状态,而潜在的线程问题也在逐渐加剧。因此,今年 1 月,Jimmy Bogard将 AutoMapper 4.2 版本中的静态函数一律标记为过时(obselete)方法,并打算最终完全移除这些函数。

在我开发 AutoMapper 4.2 版本的过程中,脑海中突然有灵光一闪。过去这十年间,我多次在讲座与播客中谈到了如何长期维护开源代码的问题。对于 AutoMapper,我最大的遗憾就是在一开始设计了一套静态的 API。AutoMapper 最初的测试与原型中都是通过“Mapper.CreateMap”与“Mapper.Map”等方法调用的。当时我向我的老板 Jeffrey Palermo 展示了我的代码,并询问他对代码的看法。他当时说道:“这看上去很棒 Jimmy,不过 API 似乎不应该设计成静态的”,而我则回应说:“开玩笑吧,这不可能!”。

之后,我开始意识到静态函数的问题,至今都为此感到懊悔。在即将发布的新版本中,我利用这次机会设计了一个不再使用静态方法的原型,它表现得很出色,我也准备好将整个静态 API 标记为过时方法。

这一改动也确实造成了某些问题。AutoMapper 的特性之一是支持 fluent API,它能够配合 LINQ 表达式链工作。这一特性需要用到扩展方法,而扩展方法往往都是通过静态函数的方式定义的。

我选择的临时方案是仍然提供对 LINQ 的支持,但改变了它的方式,使其不再利用全局的状态。使用者需要将 AutoMapper 配置信息传递给 LINQ 表达式,这种方式稍嫌冗长,但从某些方面来看,它提供了更大的灵活性。

以下示例是从“静态API 迁移指南”中所摘录的一段代码:

复制代码
public class ProductsController : Controller {
public ProductsController(MapperConfiguration config) {
this.config = config;
}
private MapperConfiguration config;
public ActionResult Index(int id) {
var dto = dbContext.Products
.Where(p => p.Id == id)
.ProjectTo(config)
.SingleOrDefault();
return View(dto);
}
}

可就在一个月后,Jimmy Bogard 又决定让这些静态函数重新回归。他写道:

静态 API 的一大困扰在于使用者可以随时对配置进行改动,而我却无法强制要求使用者对配置的步骤进行清理。但在进一步思考之后,我发现静态 API 的使用并没有任何问题,它只是要求使用者在进行映射之前必须完成初始化工作。因此我决定在后续版本中仍然允许这种使用方式。实例 API 如今已经彻底完善了,而静态 API 实际上只是一种轻量级的封装,使用者可以简单地调用静态 Initialize 方法,而无需直接调用实例的构造函数。

新发布的版本移除了某些过时属性,并且恢复了在 LINQ 映射时使用静态配置的特性。

关于应当使用有状态的静态函数,还是只允许使用实例方法,InfoQ 希望聆听读者的意见。

查看英文原文 AutoMapper and the Static Class Debate

2016-03-16 19:002479
用户头像

发布了 428 篇内容, 共 170.9 次阅读, 收获喜欢 36 次。

关注

评论

发布
暂无评论
发现更多内容

遇到消息队列选型肿么办

CTO技术共享

个人成长 消息队列 10月月更

大数据开发培训怎么选?

小谷哥

React组件设计模式-纯组件,函数组件,高阶组件

xiaofeng

React

微服务——想说爱你不容易

为自己带盐

个人感想

大数据开发培训学习哪家机构好

小谷哥

CTO技术共享整理出来的十个Python自动化脚本

CTO技术共享

Python 个人成长 10月月更

【CSPO认证】11月19-20日在线周末班 | 全国招生

ShineScrum捷行

Scrum 敏捷 产品负责人 CSPO 产品经理培训

Vue.nextTick核心原理

yyds2026

Vue

大厂被裁,疫情之下,一个offer都没,测试人如何破局?

千锋IT教育

升级到React-Router-v6

xiaofeng

React

Confidential Containers:云原生机密计算基础设施

OpenAnolis小助手

开源 cncf 龙蜥 机密计算 沙箱

渲染行业的未来发展趋势

Finovy Cloud

渲染 云渲染 本地渲染

SAP | 详解abap数据类型

暮春零贰

SAP abap 10月月更

没想到!我在简历上写了“精通MySQL”,阿里面试官跟我死磕后就给我发了高薪offer

程序知音

Java MySQL 数据库 后端技术

技术分享| 消息队列Kafka群集部署

anyRTC开发者

nginx kafka zookeeper 分布式 消息

java开发技术培训费用是多少

小谷哥

3M互助公排dapp系统开发智能合约定制

开发微hkkf5566

Dell UltraSharp 27显示器,创造你想要的“视”界

科技热闻

vue3实战-完全掌握ref、reactive

yyds2026

Vue

web前端开发课程培训哪家好

小谷哥

前端开发的程序员还有前途吗

小谷哥

React组件通信

xiaofeng

React

什么是无代码?企业为什么要用无代码进行数字化转型?

优秀

数字化转型 无代码

TiKV 源码阅读三部曲(一)重要模块

PingCAP

TiKV 源码解读

SAP | 认识数据元素和域

暮春零贰

SAP abap 10月月更

细说React组件性能优化

xiaofeng

React

极客时间运维进阶训练营第一周作业

好吃不贵

vue实战-深入响应式数据原理

yyds2026

Vue

vue中的几个高级概念

yyds2026

Vue

研发分享 | StoneDB 如何给 Tianmu 引擎增加 delete 功能 #1 调研之旅

StoneDB

数据库 HTAP StoneDB 10月月更 企业号十月PK榜

CTO技术共享整理九个shell脚本

CTO技术共享

个人成长 DDoS 10月月更

AutoMapper及静态类之争论_.NET_Jonathan Allen_InfoQ精选文章