繁体   English   中英

抽象——我如何创建一个通用的 static 方法让几种类型在 Dart/Flutter 中流过?

[英]Abstraction - How do I create a generic static method for several types to flow through in Dart/Flutter?

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

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

我目前正在为每个 object 做这样的事情:
我非常确定您可以看到这会如何让某人发疯,我的应用程序中有 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);
   }      

   ...

}

我将从我的书签中导航到一个关于 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;
    }
  }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM