Apex Items — Versioned, Not Versioned & Change Rules

DEX455 - Apex 部署与托管包完全指南

📄 第 466 页 🎬 视频课程

课程章节介绍

同学们,我们花几分钟来看一下这张幻灯片,它讲的是一些在Salesforce开发中,特别是做托管包的时候,关于Apex代码版本化和修改限制的重要规则。 首先,大家一定要理解一个点:并不是所有的Apex项目都“版本化”了。什么意思呢?如果你是在一个普通的Salesforce环境中直接写代码,比如你在开发者版里练手,那其实你的每一次代码改动,都会立刻反映到所有引用它的地方,没有版本号的概念。但是,一旦你开始创建托管包,而且这个包发布了不同的版本,那情况就完全不一样了。对于托管包里的Apex类、方法这些东西,它们就和包的版本绑定了。这样做的好处是,你可以让老版本的客户继续使用旧的行为,而不受你最新代码改动的影响——这就是“版本化”的意义。 那这个幻灯片告诉我们,托管包里的一些Apex项目,注意,是一些,并没有被版本化。具体来说,有哪些呢?比如你自己定义的自定义异常类(异常类是不会被版本化的),还有Apex里定义的枚举类型(枚举也是),另外还有那些被标记为 @Deprecated 的东西,也就是我们接下来要讲的“废弃”标记。这些项目,一旦你在新版本包里做了修改,它就会影响到所有已经安装了这个包的任何版本的订阅者。所以对这些非版本化的东西,改动真的要特别小心,因为你的改动直接跨版本生效了。 接着我们来看访问修饰符的更改规则。在编写包的时候,我们可能会想在以后的新版本中扩大某个方法的可见性,或者改变它的特性。但是,这里有一堆限制,而且这些限制是不可逆的。首先,你可以“扩大”访问权限。比如,你在第一个版本里把一个方法声明成 private 的,那么后续版本你可以把它改成 protected,这没问题,再往后你甚至能把它改成 public,最后甚至改成 global。注意这里的顺序:私人 → 受保护 → 公开 → 全局。只能从小到大扩,不能从大到小缩。为什么呢?因为你一旦公开了某个API,就有订阅者可能依赖它,你突然缩小权限,订阅者的代码就报错了。所以,只能扩大,不能缩小。还有,如果你当初定义了一个抽象类(abstract),你以后可以把它改成虚拟的(virtual),因为 virtual 是 abstract 的超集,virtual 类允许自己有实现,而 abstract 强制子类实现,所以把它从抽象变虚拟相当于放宽了限制,这是允许的。但是反过来,你绝对不能把 virtual 改成 abstract,也不能把 abstract 直接删掉。更严格的是,一旦声明为 global 和 virtual,这两个修饰符永远不能删除。因为 global 表示跨命名空间的公开API,你一删,所有外部调用全挂,所以Salesforce禁止你删。virtual 也一样,一旦声明,就永远不能收回,因为可能有子类在依赖着这种可重写的行为。抽象也不能删除,理由类似。 再来看 @Deprecated 这个注解。它的作用就是:当你准备在未来的版本里移除某个标识符(类、方法、变量等),但你现在还不想让它立刻消失,你可以先标记它为“废弃”。对于已经安装了旧版本包的现有订阅者来说,这些被废弃的东西依然完全有效,代码能正常运行。但重点是,对于新的订阅者,也就是那些首次安装你新版本包的人,这些被 @Deprecated 标记的东西对他们是不可见的——他们无法在代码提示里看到,也无法调用。这给了老客户一个缓冲期,让他们修改自己的代码,同时又能防止新用户不小心使用即将淘汰的API。不过注意,在托管包的Beta测试版本里,@Deprecated 的东西还是可见的,这是为了让你在发布前能充分测试过渡效果。只有在你正式发布(上传)了托管已发布版本后,它们才真正对新订阅者隐藏。 最后还有几个不能做弃用操作的特殊情况:你不能弃用 Web Service(也就是那些被声明为 webservice 关键字的方法),因为 web service 一般是同步 SOAP API 的一部分,你直接弃用它,会导致所有依赖它的集成系统突然找不到方法,这风险很大,所以 Salesforce 不允许。还有,你不能单独弃用枚举类型里的某一个值,要是真想弃用整个枚举,你必须整体弃用这个枚举类型。同样的,接口里的某个方法不能单独弃用,抽象类里的某个抽象方法也不能单独弃用。因为这些都属于一个整体定义的一部分,部分弃用会破坏整个类型契约的完整性。 总结一下,为了包的安全演进,你要记住:非版本化的项目(异常、枚举、废弃项)改动全局生效;访问修饰符只能扩大不能缩小,global 和 virtual 一加就永远不能撤;@Deprecated 是优雅迁移的利器,但要注意它对新订阅者的隐藏,以及它不能用于 web service、枚举值、接口方法和抽象方法。好了,这一页内容虽然不多,但规则密集,希望大家结合托管包开发的实践经验来体会这些限制存在的意义。下一节我们继续。

关键词

Apex Salesforce Developer Guide