Python Dart/Flutter 类似装饰器的设计模式?
Python decorator-like design pattern for Dart/Flutter?
我希望在类似装饰器的功能中有通用的 try/catch/finally 逻辑,可以“包装”一个函数或 class 方法。考虑场景:
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 中的注释,不适用于此处。
更新
根据 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();
});
}
这基本上就是 package:test
中的 test()
(或 Flutter 中的 testWidgets()
)所做的。
更新评论中描述的案例:如果方法 return Future
s 没有太大区别。例如,如果您开始于:
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();
});
}
我希望在类似装饰器的功能中有通用的 try/catch/finally 逻辑,可以“包装”一个函数或 class 方法。考虑场景:
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 中的注释,不适用于此处。
更新
根据 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();
});
}
这基本上就是 package:test
中的 test()
(或 Flutter 中的 testWidgets()
)所做的。
更新评论中描述的案例:如果方法 return Future
s 没有太大区别。例如,如果您开始于:
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();
});
}