首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Scala -如何在不包装所有方法的情况下创建包装器类

Scala -如何在不包装所有方法的情况下创建包装器类
EN

Stack Overflow用户
提问于 2021-02-06 03:33:04
回答 1查看 186关注 0票数 0

我有一个第三方类,我不能修改。我想添加一个透明的retry功能。因此调用者不知道重试正在幕后进行。我遇到过两种第三方类。一个是我可以扩展的,另一个是不能扩展的(私有或受保护的)。对于我不能扩展的一个,这里是我的解决方案:

代码语言:javascript
运行
复制
class 3rdPartyClassA {
  def doSomething()
} 

class MyAppClassA {
  val 3rdpartyobjA = new 3rdPartyClassA()
  def doSomething() {
    Retry.retry(3rdpartyobjA.doSomething()) //wrapping 3rdparty call with retry
  }
}

object ClientFactory {
  def get3rdPartyclassA() = new MyAppClassA
}

class CallerCode {
  ClientFactory.get3rdPartyclassA().doSomething() //doSomething is called with Retry
} 

在上面的解决方案中,我必须为3rdPartyClassA中的每个方法创建一个包装器方法。即使我可以扩展3rdPartyClassA,我也必须重写每个方法来添加Retry逻辑。有没有办法避免这种情况?像运行时一样,我可以说这个类的每个方法调用都应该包含在我的Retry逻辑中。如果是这样,该解决方案的缺点是什么?

EN

回答 1

Stack Overflow用户

发布于 2021-02-07 08:22:21

对于这个问题没有直接的解决方案。您可以使用Dynamic特征并使用反射调用底层对象的方法。https://www.scala-lang.org/api/current/scala/Dynamic.html但是,如果你这样做,类型安全就会被抛在脑后,这不仅会导致错误,还会降低性能,使IDE变得无用。我宁愿接受包装样板,也不愿采用这种方法。

您还可以使用宏实现selectDynamic,这至少可以恢复类型安全。但这也不是一个好主意,因为当前形式的宏在Scala3中消失了,这是有充分理由的。

另一种可能是编写一个源代码生成器,它将使用反射生成样板。下面是关于如何将其与sbt:https://www.scala-sbt.org/1.x/docs/Howto-Generating-Files.html集成的一些信息,但除非包装类的API非常大,否则可能更快的方法是咬住子弹,手工编写样板文件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66069525

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档