这种情况是否过度使用抽象?

时间:2010-06-21 17:47:17

标签: oop

我们正在使用其他人提供的图书馆。最近由于该库的变化,我们的项目有500个错误。迁移到新库时,我们发现只有15个API失败,500个错误重复(这15个错误的倍数出现,因为同一次调用被多次使用)。

因此,对于迁移,我建议创建另一个内部静态包装类,它包装那些库API调用。因为如果要再次更改库,我们将需要更少的代码来进行更改,因此将来代码变得更容易维护。而且通过包装调用,我们可以避免人为错误(或意外(重载)API使用)。

但是有些人在这里没有看到另一个包装类的重点,他们觉得完全是不必要的。他们唯一的论点是,由于大多数API更改只是一个衬里,我们总是可以使用CTRL + H(查找和替换)来更改它们。并且他们还说我建议的这个额外的抽象会消除可读性(因为它隐藏了编码器/读者的另一个方法名称后面的实际API调用(尽管有意义))。

这里最好的方法是什么?我的建议错了吗?

5 个答案:

答案 0 :(得分:12)

这实际上被称为Adapter模式,它是专门针对您的确切问题创建的....

适配器专门用于 NOT 添加功能,只是为了使API的接口适应调用者期望的接口。接口只是一个方便的OO工具,以一致和可管理的方式实现适配器功能,模式本身基本上描述了如何解决问题。

答案 1 :(得分:8)

使用自定义包装器包装不稳定的API和库是一种相对常见的做法。 例如,一个常见的用途是将该库的例外转换为您的例外术语。

更常见的是,这些包装器被称为适配器,虽然适配器(IMHO)更多的意思是提供一方所需的功能,同时隐藏另一方的确切“语言”,而不是因为另一方不稳定。

你提到静态的使用 - 我通常不喜欢使用这些。恕我直言,有时候有一个界面代表你需要的功能,然后在这些子类型中的一个使用第三方库时具有该界面的子类型。这样做的好处是,有一天可以切换到另一个供应商,而无需更改系统中的每个呼叫。

无论哪种方式,你通常都在正确的轨道上。恕我直言,任何认为CTRL-H是一个有效的重构工具的人都在寻找麻烦。他们至少在代码中使用getter和setter(如果适用)吗?

另外,可读性部分对我来说不清楚。具有可读名称的适配器与具有可读名称的原始API一样好。

答案 2 :(得分:2)

如果API正在发生变化,包装器是保护自己的唯一方法。如果您已经确定了一个正在改变的API,那么您的项目将面临很大的风险。使用包装器降低这些风险还可以让您在切换到其他库时保护自己。

要实现包装器,您必须创建包装器并进行搜索和替换。

无论哪种方式,由于最初的API更改,您仍然需要触摸所有通话,因此我没有看到额外的小额投资是一个问题。

答案 3 :(得分:1)

很难说不知道你的代码,但我觉得外观/适配器是从你自己的代码分离api调用的好方法。我不会说这是必要的,但它更明确的imho。

答案 4 :(得分:0)

这取决于API正在做什么以及添加另一层是否真的增加了绝缘/封装,或者它是否只是添加了另一层间接。如果API中的更改需要更改包装器的公共接口,那么它就会妨碍。

当您可以在对应用程序有意义的抽象级别公开功能,隐藏不需要的API灵活性并标准化访问所需功能的方式时,包装层最适合。这还可能涉及使用更具体到您的问题域的函数和参数名称,这可以减少理解API如何集成到您的应用程序中的概念上的困难。