Dart/Flutter 的类似 Python 装饰器的设计模式?

2023-11-21

我希望在类似装饰器的功能中拥有通用的 try/catch/finally 逻辑,可以“包装”函数或类方法。考虑以下场景:

Class MyClass {
  void someMethodA() {
    doSomeInitialWork();
    
    try {
      doSomething();
    } catch (err) {
      throw err;
    } finally {
      doSomeCleanUpWork();
    }
  }

  void someMethodB() {
    doSomeInitialWork();
    
    try {
      doSomethingElse();
    } catch (err) {
      throw err;
    } finally {
      doSomeCleanUpWork();
    }
  }
}

等等等等。每种方法的独特部分只是try身体。如果我有一堆方法,其中一些方法需要相同的逻辑,是否有一种“好的”方法来避免冗余代码?

理想情况下,它的语法可以是:

@wrapper
void someMethodA() {
  doSomething();
}

@wrapper
void someMethodB() {
  doSomethingElse();
}

MyClassInstance.someMethodA(); // call it like this and the wrapper takes care of everything

但我知道这些是 Dart 中的注释,在这里不适用。

UPDATE

根据 jamesdlin 的回答,我尝试将匿名函数解决方案合并到 futures/async/await 场景中:

Future<dynamic> trySomething(Future<dynamic> Function() callback) async {
  doSomeInitialWork();

  try {
    return await callback();
  } catch (err) {
    throw err;
  } finally {
    doSomeCleanUpWork();
  }
}

class MyClass {
  Future<List<String>> someMethodA() async {
    return await trySomething(() async {
      return await someApiCall();
    });
  }
}

这似乎可行,但看起来有点混乱。我不确定我在 async/await 示例中所做的是否合适。


Dart 中的匿名函数相当常见(与 Python 不同,其中lambda非常受限制)。

因此,您可以创建一个辅助函数,将唯一部分作为回调。

void trySomething(void Function() body) {
  doSomeInitialWork();

  try {
    body();
  } catch (err) {
    throw err;
  } finally {
    doSomeCleanUpWork();
  }
}

void someMethodA() {
  trySomething(() {
    doSomething();
  });
}

void someMethodB() {
  trySomething(() {
    doSomethingElse();
  });
}

基本上就是这样test() from package:test (or testWidgets()来自 Flutter)做。


评论中描述的情况更新:如果方法返回,则没有太大不同Futures。例如,如果您从以下内容开始:

Future<List<String>> someMethodA() async {
  return await blah();
}

那么你可以这样做:

Future<R> trySomethingAsync<R>(Future<R> Function() body) async {
  doSomeInitialWork();

  try {
    return await body();
  } catch (err) {
    throw err;
  } finally {
    doSomeCleanUpWork();
  }
}

Future<List<String>> someMethodA() {
  return trySomethingAsync(() async {
    return await blah();
  });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dart/Flutter 的类似 Python 装饰器的设计模式? 的相关文章

随机推荐

  • 如何从类函数内部访问对象属性[重复]

    这个问题在这里已经有答案了 我的 Javascript 类之一有时需要用 Json 更新 我一直在做一个函数 在给定一个 id 的情况下更新数据数组 但现在我想把它做得更封装 函数更新 在类内部 我做了什么 function File da
  • Angular 2 使用 FormBuilder 访问嵌套 FormArray

    首先 我刚刚从 Angular 2 开始 我正在尝试构建一个嵌套表单并验证它 这是我的 ts 文件的一部分 ngOnInit this myForm this formBuilder group projects this formBuil
  • JavaScript 的正则表达式表示法有什么问题?

    我正在读道格拉斯 克罗克福德的网页 JavaScript 世界上最容易被误解的编程语言 我不禁注意到 在 设计错误 下 他提到了 文字正则表达式的符号 他到底在说什么 JavaScript 的正则表达式表示法有什么问题 为什么 可能与它迫使
  • 将取消引用的智能指针的地址传递给需要原始指针的函数

    假设我正在使用需要使用原始指针的库或框架 使用拥有一些数据的智能指针 然后将取消引用的智能指针的地址传递给需要原始指针的函数 这是有效的做法吗 是的 这是有效的做法 这std智能指针有一个get 成员函数正是为了这个目的 一般来说 当您通过
  • UDF 中的 COLLATE 未按预期工作

    我有一个带有文本字段的表格 我想选择文本全部大写的行 该代码按其应有的方式工作 并返回ABC SELECT txt FROM SELECT ABC AS txt UNION SELECT cdf t WHERE txt COLLATE SQ
  • 只保留字符串中的前 n 个字符?

    JavaScript 有没有办法删除字符串的末尾 我只需要保留字符串的前 8 个字符并删除其余的 const result Hiya how are you substring 0 8 console log result console
  • 在 C++ 中,有什么理由用 for(;condition;) 替换 while(condition) 吗?

    好像 while condition do stuff 完全等价于 for condition do stuff 有什么理由使用后者而不是前者 没有good据我所知原因 您使用不增加任何内容的 for 循环故意误导人们 Update 根据O
  • ASP.NET MVC 4.5.2 连接到 IdentityServer4

    我有一个在 ASP NET MVC 4 5 2 上运行的网站 我有一个 IdentityServer4 服务器正在运行 但是当我尝试对其进行身份验证时 我得到 invalid request 对于 ASP NET Core MVC文档 ha
  • 图像未在 React 中加载

    无法显示图像 出现未找到错误 但我已经提供了它的完整路径 我不知道我哪里错了 class App extends React Component render return div h1 hello h1 img src home priy
  • 我应该在配置文件之外使用 env() 吗?

    我偶然发现了这个https laravel com docs 5 4 configuration configuration caching在文档中 这让我有点困惑 当我想要一个环境变量时 我使用 env 函数返回我想要的内容 根据上面的链
  • postgres 上慢速选择不同查询

    我在一个基本上收集日志信息的表上经常执行以下两个查询 两者都从大量行中选择不同的值 但其中的不同值少于 10 个 我分析了该页面完成的两个 不同 查询 marchena gt explain select distinct auditrec
  • 如何将月份格式化为 mmm 格式?

    我正在尝试使用 VBA 在 Excel 中格式化日期 即当前月份mmm格式 不知何故 我得到的是上个月 而不是当前月份 我查了一下 我的电脑月份是二月 但我得到的是一月 这是我的代码 Cells 1 2 Format month Date
  • 为什么GCC编译的C程序需要.eh_frame部分?

    测试在 32 位 x86 Linux 上进行gcc 4 6 3 使用时gcc编译一个C程序和使用readelf要检查部分信息 我可以看到 eh frame部分和 eh frame hdr里面的部分 例如 这是二进制程序的部分信息Perlbe
  • 如何使用 System.IdentityModel.Tokens.Jwt 使用 Google OAuth2 兼容算法 RSA SHA-256 生成 JWT?

    我正在尝试创建一个 JWT 以使用服务帐户进行授权 如中所述谷歌文档 using System IdentityModel Tokens Jwt 我有以下代码 byte key Convert FromBase64String var ce
  • Android ADB 重新分发 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 您是否可以将 Android ADB 重新分发给最终用户 安装程序中是否包含可能包含的分发 软件包 我们正在考虑使用它来在我们的 Android 应用程序和桌面应用程序之间提供 US
  • Apple 推送通知注册和设备令牌 收到说明了吗?

    我正在开发一个 iPhone 应用程序Apple Push Notification一体化 对此我有一些疑问 如果用户单击 APNS 注册警报中的 不允许 按钮 我们的代码是否仍会从 APNS 接收设备令牌 我测试过 当用户关闭iPhone
  • 如何在正在运行的 docker 容器中设置环境变量

    如果我有一个不久前启动的 docker 容器 那么在该正在运行的容器中设置环境变量的最佳方法是什么 当我运行 run 命令时 我最初设置了一个环境变量 docker run name my wordpress e VIRTUAL HOST
  • protobuf 消息是否跨版本的 protobuf 兼容

    我开始使用 protobuf 2 2 0 构建一个应用程序 因为它是最新的 现在我正在考虑升级到最新的 protobuf 2 4 0a 如果我这样做 应用程序的一个版本生成的消息是否仍然可以被同一架构的另一版本读取 或者我会破坏什么东西 那
  • 通过多个条件匹配和替换数据框的列

    干杯 我有两个具有以下结构的数据框 DF1 Airlines HeadQ Date Cost Index American PHX 07 31 2016 220 American ATL 08 31 2016 150 American AT
  • Dart/Flutter 的类似 Python 装饰器的设计模式?

    我希望在类似装饰器的功能中拥有通用的 try catch finally 逻辑 可以 包装 函数或类方法 考虑以下场景 Class MyClass void someMethodA doSomeInitialWork try doSomet