Nano Hash - криптовалюты, майнинг, программирование

Шаблон дизайна, подобный декоратору Python для Dart / Flutter?

Я хотел бы иметь общую логику 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, и здесь они не применимы.

ОБНОВЛЕНИЕ

Следуя ответу 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, уместно.


Ответы:


1

Анонимные функции в 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() из package:test (или 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();
  });
}
17.02.2021
  • Чтобы немного усложнить ситуацию, что, если методы возвращают фьючерсы? Так что вместо void someMethodA() {} это Future<List<String>> someMethodA() async {return await blah();}. Я не уверен, как сейчас выглядит анонимная функция и как обернуть тело. 17.02.2021
  • @ user1087973 Извините, я не видел ваш комментарий раньше. Если вы еще не поняли это самостоятельно, я обновил свой ответ для вашего случая. 10.03.2021
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..