抽象 - 如何为 Dart/Flutter 中的多种类型创建通用静态方法?

发布于 2025-01-18 06:04:51 字数 1728 浏览 4 评论 0原文

好的,我正在尝试减少我应用程序的大量样板代码。现在,我看到需要进行一些重构和认真的抽象。

我想为我的数据库代码抽象CRUD操作。现在,我正在创建一个单独的文件并为每个对象复制代码。我觉得必须有更好的方法,但我不知道如何在使用仿制药时保持显式类型的安全性。

我目前为每个对象做这样的事情:
我非常确定您可以看到这将如何驱动某人,我的应用程序中有45个以上的对象……而且许多物体比这更复杂。

abstract class HouseDatabaseAPI {

  /// CREATE EVENT
  /// Create house for authorized user
  static Future<void> createHouse({required House newHouse}) async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    await houseBox.put(newHouse);
  }

  /// READ EVENT
  /// Get house for authorized user
  static Future<House?> getHouse() async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    House? house = houseBox.getAt(0);
    return house;
  }

  /// UPDATE EVENT
  /// Update house for authorized user
  static Future<void> updateHouse({House? updatedHouse}) async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    await houseBox.putAt(0, updatedHouse!);
  }

  /// DELETE EVENT
  /// Delete house from the local machine
  static Future<void> deleteGroup() async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    await houseBox.deleteAt(0);
  }
}

当然,我希望这是严格键入而不是动态的。 我希望能够做什么,而不是大规模的流控制语句(粗糙的伪代码):


enum DatabaseAction {
   create,
   read,
   update,
   delete,
}

abstract class DatabaseRoutingAPI {
   
   Future<T> globalDatabaseCreateAction({
      DatabaseAction databaseAction,
      Object object,
      String databaseName,
      }) async {
         Box<T> houseBox = await Hive.openBox<T>(databaseName);
         await houseBox.put(object);
   }      

   ...

}

Okay, I'm trying to cut back on an enormous amount of boilerplate code for my app. Right now I see the need for some refactoring and serious abstraction.

I want to abstract CRUD actions for my database code. Right now I'm creating a separate file and duplicating the code for each object. I feel like there must be a better way but I don't know how to keep explicit type safety while abstracting with generics.

I'm currently doing something like this for EACH object:
I'm very sure you can see how this would drive someone nuts, I have 45+ objects in my app... and many are more complex than this.

abstract class HouseDatabaseAPI {

  /// CREATE EVENT
  /// Create house for authorized user
  static Future<void> createHouse({required House newHouse}) async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    await houseBox.put(newHouse);
  }

  /// READ EVENT
  /// Get house for authorized user
  static Future<House?> getHouse() async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    House? house = houseBox.getAt(0);
    return house;
  }

  /// UPDATE EVENT
  /// Update house for authorized user
  static Future<void> updateHouse({House? updatedHouse}) async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    await houseBox.putAt(0, updatedHouse!);
  }

  /// DELETE EVENT
  /// Delete house from the local machine
  static Future<void> deleteGroup() async {
    Box<House> houseBox = await Hive.openBox<House>('house_box');
    await houseBox.deleteAt(0);
  }
}

Of course I want this to be strictly typed and NOT dynamic.
What I would like to be able to do instead of a massive flow control statement (rough pseudocode):


enum DatabaseAction {
   create,
   read,
   update,
   delete,
}

abstract class DatabaseRoutingAPI {
   
   Future<T> globalDatabaseCreateAction({
      DatabaseAction databaseAction,
      Object object,
      String databaseName,
      }) async {
         Box<T> houseBox = await Hive.openBox<T>(databaseName);
         await houseBox.put(object);
   }      

   ...

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫卆 2025-01-25 06:04:51

我将引导您从我的关于 Hive 数据处理的书签中找到一个很好的来源 -> 此处

在这里我将尝试回答您的问题:

abstract class Database {
  Box get box;
  T get<T>(String id);
  List<T> getAll<T>();
  Future<void> delete(String id);
  Future<void> deleteAll(List<String> keys);
  Future<void> addUpdate<T>(String id, T item);
}

class DatabaseImplementing implements Database {
  const DatabaseImplementing(this._box);
  
  final Box _box;
  
  @override
  Box get box => _box;

  @override
  T get<T>(String id) {
    try {
      final data = box.get(id);
      
      if (data == null) {
        throw Exception('$T not in the box.');
      }
      
      return data;
    } catch (_) {
      rethrow;
    }
  }

  @override
  List<T> getAll<T>() {
    try {
      final data = box.toMap().values;
      
      if (data.isEmpty) {
        throw Exception('$T not in the box.');
      }

      return data.toList().cast<T>();
    } catch (_) {
      rethrow;
    }
  }

  @override
  Future<void> delete(String id) async {
    try {
      await box.delete(id);
    } catch (_) {
      rethrow;
    }
  }

  @override
  Future<void> addUpdate<T>(String id, T item) async {
    try {
      await box.put(id, item);
    } catch (_) {
      rethrow;
    }
  }

  @override
  Future<void> deleteAll(List<String> keys) async {
    try {
      await box.deleteAll(keys);
    } catch (_) {
      rethrow;
    }
  }
}

当然还有很多其他方法可以做到这一点。

I will navigate you to one good source from my bookmarks about Hive data handling -> here

And here I will try to answer your question:

abstract class Database {
  Box get box;
  T get<T>(String id);
  List<T> getAll<T>();
  Future<void> delete(String id);
  Future<void> deleteAll(List<String> keys);
  Future<void> addUpdate<T>(String id, T item);
}

class DatabaseImplementing implements Database {
  const DatabaseImplementing(this._box);
  
  final Box _box;
  
  @override
  Box get box => _box;

  @override
  T get<T>(String id) {
    try {
      final data = box.get(id);
      
      if (data == null) {
        throw Exception('$T not in the box.');
      }
      
      return data;
    } catch (_) {
      rethrow;
    }
  }

  @override
  List<T> getAll<T>() {
    try {
      final data = box.toMap().values;
      
      if (data.isEmpty) {
        throw Exception('$T not in the box.');
      }

      return data.toList().cast<T>();
    } catch (_) {
      rethrow;
    }
  }

  @override
  Future<void> delete(String id) async {
    try {
      await box.delete(id);
    } catch (_) {
      rethrow;
    }
  }

  @override
  Future<void> addUpdate<T>(String id, T item) async {
    try {
      await box.put(id, item);
    } catch (_) {
      rethrow;
    }
  }

  @override
  Future<void> deleteAll(List<String> keys) async {
    try {
      await box.deleteAll(keys);
    } catch (_) {
      rethrow;
    }
  }
}

Sure it's many other ways to do this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文