【问题标题】:Generic code generation vs Hardcoded API calls: Best approach通用代码生成与硬编码 API 调用:最佳方法
【发布时间】:2015-10-03 15:56:03
【问题描述】:

我陷入了一个想知道可以应用于此的最佳实践的场景中。我在一个电子商务网站上工作,处理订单、发货、发票等。

除了在我的应用程序中创建 UI 之外,我还能够发送/接收来自不同供应商的数据(通过供应商 apis xml/json)。该应用程序可以向在我的应用程序中创建的供应商发布订单/发货,或者从供应商处获取所有订单/发货以导入我的应用程序。场景因供应商而异。

我的问题是处理这个问题的最佳方法是什么。以下是我想到的两种方法。我现在正在使用第一种方法,但我正在考虑它是否适合在这种情况下使用。

1.) 我创建了一个通用代码来基于 XPATH 生成 JSON/XML。例如,对于下面的 XML 生成,我使用 XPATH 作为 Orders.order.orderNumber <Orders><order><orderNumber>testorder</orderNumber></order></Orders> XPATH 存储在数据库中,根据数据库中配置的不同 XPATH,生成完整的 JSON/XML 并发送给供应商(数据库中也配置了 GET/POST)。

我认为这种方法的优点是将新供应商添加到系统中的工作量最少。 我认为它的缺点是 XML/JSON 生成会经历大循环。由于要为供应商调用的 API(订单 GET 等)大多是固定的,这似乎是一个缺点。

2.) 我创建单独的服务来处理每个供应商的调用,创建处理每个调用的方法,并将 XML 硬编码到应用程序中(无需通过 XPATH 在 DB 中进行配置)。 例如,对于 2 个供应商 SuppA 和 SuppB。对于 SuppA 的订单列表将被下载,对于 SuppB 的发货将被张贴。 因此,我的应用程序中将有 2 个服务相互独立地处理每个供应商调用,1 个用于 SuppA,另一个用于 SuppB。 SuppA 服务将调用订单 GET api,SuppB 服务将调用 Shipments POST api。

我认为这样做的好处是它会很快,因为不需要生成 XML/JSON,因为只有所需的调用将被编码在每个供应商的服务代码中。 我认为它的缺点是只能调用固定服务。我的第一种方法可以通过 DB 更改任何内容,但在此代码中需要更改。

请就此提出建议。哪种方法最适合这种情况,通用数据库配置还是硬编码的单独供应商服务?

【问题讨论】:

  • 每个供应商的数据模型或模式是否彼此不同?
  • 是的,每个供应商的数据模型都不同。它们通过其服务 API 公开。我们可能会向一个供应商发送一组特定的字段,但向另一个供应商发送一组不同的字段,具体取决于他们支持的请求 xml/json。

标签: java json xml web-services e-commerce


【解决方案1】:

我个人认为第二种方法更接近我选择的解决方案:您有许多必须与之通信的外部接口。根据您的描述,我了解到,它们都处理 XML 或 JSON。考虑应该快速添加新供应商的情况变成了可维护性问题。

所以我会为每个供应商定义一个具有匹配数据模型的接口。在您这边,您将有一个不同的数据模型来表示订单、发货、发票等等。然后,您可以使用 Dozer 之类的映射框架将数据从一种表示形式转换为另一种表示形式。

然后您可以使用不同的框架 JAXBGSON 将您的对象转换为 XML 或 JSON。

【讨论】:

  • 还有一个问题,我还集成了 Quickbooks,它曾经有 Class/Objects SDK 而不是 XML/JSON。我使用反射 API 编写了一个通用代码来实现它。类名和方法存储在数据库中,并基于该类在运行时动态创建,并通过反射调用方法并设置数据值。在这种情况下也应用第二种方法是否是一种好习惯,否则我们需要在所有情况下在代码本身中显式调用所有 setter 和 getter?
  • GSON 默认访问字段,JAXB 可以配置是使用字段还是使用 getter/setter 方法。有关详细信息,请查看 stackoverflow.com/questions/11385214/…stackoverflow.com/questions/6203487/…
  • 非常感谢。 Dozer 与 JAXB 或 GS​​ON 的组合可以解决问题。 :)
【解决方案2】:

首先为代码编写单元测试。这很可能会导致您问自己是什么导致了更可测试和可维护的应用程序,以及什么以最优质的方式解决了问题。答案可能是#1 和#2 的组合。硬编码“魔法”值从来都不是一个好的选择。而且,在性能和/或可扩展性方面,不得不调用繁重的持久层并不是很好。

我建议:

  1. 将值存储在易于维护的可配置位置。
  2. 使用 Redis 或 Memcache 等缓存层允许代码以可扩展和可扩展的方式获取值。

好处:

  1. 防止硬编码。
  2. 防止硬重置/重启应用配置更改。
  3. 用于添加/删除新供应商的更多可扩展代码。
  4. 提高整体应用敏捷性。

最后一点:作为一个有趣的想法,您可以使用工厂模式动态生成供应商对象,以允许在不重新编码系统的情况下向正在运行的系统添加和删除供应商。这涉及更多,但可能是一种选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多