flutter_clean_architecture

flutter_clean_architecture

Flutter清洁架构实现的开源解决方案

flutter_clean_architecture是一个开源Flutter包,简化了Uncle Bob清洁架构的实现。该包提供了四个主要模块:App、Domain、Data和Device,并通过依赖规则确保模块间的独立性。其设计理念强调关注点分离和可扩展性,有助于提升Flutter项目的代码质量和可维护性。

FlutterClean Architecture设计模式软件架构依赖注入Github开源项目

flutter_clean_architecture 包

CI

概述

这是一个Flutter包,使得在Flutter中实现Uncle Bob的清洁架构变得简单直观。该包提供了根据清洁架构设计并针对Flutter进行调优的基本类。

安装

1. 添加依赖

在你的包的pubspec.yaml文件中添加以下内容:

dependencies: flutter_clean_architecture: ^6.0.1

2. 安装

你可以从命令行安装包:

使用Flutter:

$ flutter packages get

或者,你的编辑器可能支持flutter packages get。查看你的编辑器文档了解更多。

3. 导入

现在在你的Dart代码中,你可以使用:

import 'package:flutter_clean_architecture/flutter_clean_architecture.dart';

Flutter清洁架构入门

介绍

这是基于Uncle Bob的书籍和博客的架构。它结合了洋葱架构和其他架构的概念。该架构的主要关注点是关注点分离和可扩展性。它由四个主要模块组成:AppDomainDataDevice

依赖规则

源代码依赖只指向内部。这意味着内部模块既不知道也不依赖于外部模块。但是,外部模块既知道也依赖于内部模块。外部模块代表了业务规则和策略(内部模块)运作的机制。越往内部移动,抽象程度越高。越往外部移动,具体实现越多。内部模块不知道外部模块中存在的任何类、函数、名称、库等。它们只代表规则,完全独立于实现。

层次

Domain

Domain模块定义了应用程序的业务逻辑。它是一个独立于开发平台的模块,即它纯粹用编程语言编写,不包含平台的任何元素。在Flutter的情况下,Domain将纯粹用Dart编写,不包含任何Flutter元素。这是因为Domain应该只关注应用程序的业务逻辑,而不是实现细节。这也允许在平台之间轻松迁移,如果出现任何问题的话。

Domain的内容

Domain由几个部分组成。

  • 实体
    • 企业范围的业务规则
    • 由可以包含方法的类组成
    • 应用程序的业务对象
    • 在整个应用程序中使用
    • 当应用程序中的某些内容发生变化时,最不可能改变
  • 用例
    • 特定应用程序的业务规则
    • 封装应用程序的所有用例
    • 编排整个应用程序的数据流
    • 不应受到任何UI更改的影响
    • 如果应用程序的功能和流程发生变化,可能会改变
  • 仓库
    • 定义外层预期功能的抽象类
    • 不了解外层,只定义预期功能
      • 例如,Login用例期望有login功能的Repository
    • 从外层传递给用例

Domain代表最内层。因此,它是架构中最抽象的层。

App

AppDomain外部的层。App跨越层边界与Domain通信。然而,依赖规则从未被违反。使用多态性App通过继承类与Domain通信:实现或扩展Domain层中存在的Repositories的类。由于使用了多态性,传递给DomainRepositories仍然遵守依赖规则,因为就Domain而言,它们是抽象的。实现隐藏在多态性之后。

App的内容

由于App是应用程序的表现层,它是最依赖框架的层,因为它包含UI和UI的事件处理程序。对于应用程序中的每个页面,App至少定义3个类:ControllerPresenterView

  • 视图
    • 只代表页面的UI。视图构建页面的UI,设置样式,并依赖控制器处理其事件。视图 包含 控制器
    • 在Flutter的情况下
      • 视图由2个类组成
        • 一个继承自View,是代表视图的根Widget
        • 一个继承自ViewState,带有另一个类及其控制器的模板特化。
      • ViewState包含view getter,这实际上是UI实现
      • StatefulWidget按照Flutter的规定包含State
      • StatefulWidget只用于从其他页面传递参数给State,如标题等。它只实例化State对象(ViewState)并通过其消费者提供所需的控制器
      • StatefulWidget 包含 State对象(ViewState),而ViewState 包含 控制器
      • 总之,StatefulWidgetState都由页面的ViewViewState表示。
      • ViewState类维护一个GlobalKey,可用作其scaffold的key。如果使用,控制器可以通过getState()轻松访问它以显示snackbar和其他对话框。这很有用但是可选的。
  • 控制器
    • 每个ViewState 包含 控制器控制器提供ViewState所需的成员数据,即动态数据。控制器还实现ViewState小部件的事件处理程序,但无法访问小部件本身。ViewState使用控制器,而不是相反。当ViewState调用控制器的处理程序时,可以调用refreshUI()来更新视图。
    • 每个控制器都继承自Controller抽象类,该类实现了WidgetsBindingObserver。每个控制器类负责处理视图的生命周期事件,可以重写:
      • void onInActive()
      • void onPaused()
      • void onResumed()
      • void onDetached()
      • void onDisposed()
      • void onReassembled()
      • void onDidChangeDependencies()
      • void onInitState()
      • 等..
    • 此外,每个控制器 必须 实现 initListeners() 以初始化展示器的监听器,以保持一致性。
    • 控制器 包含 展示器控制器仓库传递给展示器,后者将与用例通信。控制器将指定展示器应为所有成功和错误事件调用哪些监听器,如前所述。只有控制器被允许从最外层的数据设备模块获取仓库的实例。
    • 控制器可以访问ViewState,并可以通过refreshUI()刷新受控小部件
  • 展示器
    • 每个控制器 包含 展示器展示器用例通信,如应用层开始时所述。展示器将有作为函数的成员,这些函数由控制器可选设置,并在用例返回数据、完成或出错时被调用(如果设置了的话)。
    • 展示器由两个类组成
      • 展示器 例如 LoginPresenter
        • 包含由控制器设置的事件处理程序
        • 包含要使用的用例
        • 使用Observer<T>类和适当的参数初始化并执行用例。例如,在LoginPresenter的情况下使用usernamepassword
      • 一个实现Observer<T>的类
        • 有对展示器类的引用。理想情况下,这应该是一个内部类,但Dart尚不支持内部类。
        • 实现3个函数
          • onNext(T)
          • onComplete()
          • onError()
        • 这3个方法代表用例的所有可能输出
          • 如果用例返回一个对象,它将被传递给onNext(T)
          • 如果出错,它将调用onError(e)
          • 一旦完成,它将调用onComplete()
        • 这些方法然后会调用展示器中由控制器设置的相应方法。这样,事件就传递给了控制器,后者可以操作数据并更新ViewState
  • 额外
    • 实用工具类(任何常用函数,如时间戳获取器等)
    • 常量类(方便使用的const字符串)
    • 导航器(如果需要)

数据

代表应用程序的数据层。数据模块是最外层的一部分,负责数据检索。这可以是对服务器的API调用、本地数据库,甚至两者都有。

数据内容
  • 仓库
    • 每个仓库 应该 实现 领域 层的Repository
    • 使用多态性,这些来自数据层的仓库可以跨层边界传递,从视图开始,通过控制器展示器一直到用例
    • 从数据库或其他方法检索数据。
    • 负责任何API调用和高级数据操作,如
      • 在数据库中注册用户
      • 上传数据
      • 下载数据
      • 处理本地存储
      • 调用API
  • 模型(不是必须的,取决于应用程序)
    • 实体的扩展,增加了可能依赖平台的额外成员。例如,对于本地数据库,这可以表现为本地数据库中的isDeletedisDirty条目。这些条目不能出现在实体中,因为那会违反依赖规则,因为领域不应该了解实现细节。
    • 在我们的应用程序中,数据层的模型将不是必需的,因为我们没有本地数据库。因此,我们不太可能需要在实体中添加依赖平台的额外条目。
  • 映射器
    • 实体对象映射到模型,反之亦然。
    • 静态类,带有静态方法,接收实体模型并返回另一个。
    • 只有在存在模型时才需要
  • 额外
    • 如果需要,可以有实用工具
    • 如果需要,可以有常量

设备

作为最外层的一部分,设备直接与平台(即Android和iOS)通信。设备负责本机功能,如GPS和平台本身存在的其他功能,如文件系统。设备调用所有本机API。

数据内容
  • 设备
    • 类似于数据中的仓库设备是与平台中特定功能通信的类。
    • 以与仓库相同的方式通过层传递:使用应用层和领域层之间的多态性。这意味着控制器将其传递给展示器,然后展示器多态地将其传递给用例,后者将其作为抽象类接收。
  • 额外
    • 如果需要,可以有实用工具
    • 如果需要,可以有常量

用法

文件夹结构

lib/
    app/                          <--- 应用层
        pages/                        <-- 页面或屏幕
          login/                        <-- 应用中的某个页面
            login_controller.dart         <-- 登录控制器继承自`Controller`
            login_presenter.dart          <-- 登录展示器继承自`Presenter`
            login_view.dart               <-- 登录视图,2个类分别继承`View`和`ViewState`
        widgets/                      <-- 自定义小部件
        utils/                        <-- 实用函数/类/常量
        navigator.dart                <-- 可选的应用导航器
    data/                         <--- 数据层
        repositories/                 <-- 仓库(检索数据,heavy处理等)
          data_auth_repo.dart           <-- 示例仓库:处理所有认证
        helpers/                      <-- 任何辅助类,如http辅助类
        constants.dart                <-- 常量,如API密钥、路由、URL等
    device/                       <--- 设备层
        repositories/                 <--- 与平台通信的仓库,如GPS
        utils/                        <--- 任何实用类/函数
    domain/                       <--- 领域层(业务和企业)纯DART
        entities/                   <--- 企业实体(应用的核心类)
          user.dart                   <-- 示例实体
          manager.dart                <-- 示例实体
        usecases/                   <--- 业务流程,如登录、登出、获取用户等
          login_usecase.dart          <-- 示例用例继承自`UseCase`或`CompletableUseCase`
        repositories/               <--- 定义数据和设备层功能的抽象类
    main.dart                     <--- 入口点

示例代码

这里查看一个小示例,在这里查看构建的完整应用程序。

View 和 ControlledWidgetBuilder

import 'package:flutter_clean_architecture/flutter_clean_architecture.dart'; class CounterPage extends View { // 可以在此处注入依赖 State<StatefulWidget> createState() => CounterState(); } class CounterState extends ViewState<CounterPage, CounterController> { CounterState() : super(CounterController()); Widget get view => MaterialApp( title: 'Flutter Demo', home: Scaffold( key: globalKey, // 使用 `View` 内置的全局键用于 scaffold 或任何其他 // 小部件为控制器提供了通过 getContext()、getState()、getStateKey() 访问它们的方法 body: Column( children: <Widget>[ Center( // 显示按钮被点击的次数 child: ControlledWidgetBuilder<CounterController>( builder: (context, controller) { return Text(controller.counter.toString()); } ), ), // 你可以在控制器内部手动刷新 // 使用 refreshUI() ControlledWidgetBuilder<CounterController>( builder: (context, controller) { return MaterialButton(onPressed: controller.increment); } ), ], ), ), ); }
响应式视图状态

为了处理 Flutter Web 上的屏幕,你可以利用响应式视图状态, 它抽象了主要的 Web 应用程序断点(桌面、平板和移动),以简化使用 flutter_clean_architecture 进行 Web 开发

例如:

import 'package:flutter_clean_architecture/flutter_clean_architecture.dart'; class CounterPage extends View { // 可以在此处注入依赖 State<StatefulWidget> createState() => CounterState(); } class CounterState extends ResponsiveViewState<CounterPage, CounterController> { CounterState() : super(CounterController()); Widget AppScaffold({Widget child}) { return MaterialApp( title: 'Flutter Demo', home: Scaffold( key: globalKey, // 使用 `View` 内置的全局键用于 scaffold 或任何其他 // 小部件为控制器提供了通过 getContext()、getState()、getStateKey() 访问它们的方法 body: child ), ); } ViewBuilder get mobileView => AppScaffold( child: Column( children: <Widget>[ // 你可以在控制器内部手动刷新 // 使用 refreshUI() ControlledWidgetBuilder<CounterController>( builder: (context, controller) { return Text('移动视图上的计数器 ${controller.counter.toString()}'); } ), ], ) ); ViewBuilder get tabletBuilder => AppScaffold( child: Column( children: <Widget>[ // 你可以在控制器内部手动刷新 // 使用 refreshUI() ControlledWidgetBuilder<CounterController>( builder: (context, controller) { return Text('平板视图上的计数器 ${controller.counter.toString()}'); } ), ], ) ); ViewBuilder get desktopBuilder => AppScaffold( child: Row( children: <Widget>[ // 你可以在控制器内部手动刷新 // 使用 refreshUI() ControlledWidgetBuilder<CounterController>( builder: (context, controller) { return Text('桌面视图上的计数器 ${controller.counter.toString()}'); } ), ], ) ); }
具有共同控制器的小部件

如果多个小部件需要使用某个 Page 的相同 Controller, 可以通过 FlutterCleanArchitecture.getController<HomeController>(context) 在该页面的子小部件中检索 Controller

例如:

import '../pages/home/home_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter_clean_architecture/flutter_clean_architecture.dart'; class HomePageButton extends StatelessWidget { final String text; HomePageButton({ this.text}); Widget build(BuildContext context) { // 使用通用控制器,假设 HomePageButton 始终是 Home 的子级 HomeController controller = FlutterCleanArchitecture.getController<HomeController>(context); return GestureDetector( onTap: controller.buttonPressed, child: Container( height: 50.0, alignment: FractionalOffset.center, decoration: BoxDecoration( color: Color.fromRGBO(230, 38, 39, 1.0), borderRadius: BorderRadius.circular(25.0), ), child: Text( text, style: const TextStyle( color: Colors.white, fontSize: 20.0, fontWeight: FontWeight.w300, letterSpacing: 0.4), ), ), ); } }

控制器

import 'package:flutter_clean_architecture/flutter_clean_architecture.dart'; class CounterController extends Controller { int counter; final LoginPresenter presenter; CounterController() : counter = 0, presenter = LoginPresenter(), super(); void increment() { counter++; } /// 显示一个 snackbar void showSnackBar() { ScaffoldState scaffoldState = getState(); // 获取状态,在这种情况下是 scaffold scaffoldState.showSnackBar(SnackBar(content: Text('你好'))); } void initListeners() { // 在此初始化 presenter 监听器 // 这些将在用例执行后成功、失败或数据检索时被调用 presenter.loginOnComplete = () => print('登录成功'); presenter.loginOnError = (e) => print(e); presenter.loginOnNext = () => print("onNext"); } void login() { // 在此传递适当的凭证 // 假设你有文本字段来检索它们等 presenter.login(); } }

Presenter

import 'package:flutter_clean_architecture/flutter_clean_architecture.dart'; class LoginPresenter() { Function loginOnComplete; // 或者 `void loginOnComplete();` Function loginOnError; Function loginOnNext; // 在登录 presenter 的情况下不需要 final LoginUseCase loginUseCase; // 从控制器进行依赖注入 LoginPresenter(authenticationRepo): loginUseCase = LoginUseCase(authenticationRepo); /// 控制器调用的登录函数 void login(String email, String password) { loginUseCase.execute(_LoginUseCaseObserver(this), LoginUseCaseParams(email, password)); } /// 处理 [LoginUseCase] 并取消订阅 void dispose() { _loginUseCase.dispose(); } } /// 用于观察 [LoginUseCase] 的 `Stream` 的 [Observer] class _LoginUseCaseObserver implements Observer<void> { // 上面的 presenter // 这不是最优的,但由于 Dart 的限制,这是一个变通方法。Dart 不 // 支持内部类或匿名类。 final LoginPresenter loginPresenter; _LoginUseCaseObserver(this.loginPresenter); /// 如果 `Stream` 发出一个值则实现 // 在这种情况下,不必要 void onNext(_) {} /// 登录成功,在 [LoginController] 中触发事件 void onComplete() { // 任何清理或准备工作都在这里进行 assert(loginPresenter.loginOnComplete != null); loginPresenter.loginOnComplete(); } /// 登录失败,在 [LoginController] 中触发事件 void onError(e) { // 任何清理或准备工作都在这里进行 assert(loginPresenter.loginOnError != null); loginPresenter.loginOnError(e); } }

UseCase

import 'package:flutter_clean_architecture/flutter_clean_architecture.dart'; // 在这种情况下,不需要参数。因此,void。否则,更改为适当的类型。 class LoginUseCase extends CompletableUseCase<LoginUseCaseParams> { final AuthenticationRepository _authenticationRepository; // 一些需要注入的依赖 // 功能隐藏在这个 // 在 Domain 模块中定义的抽象类后面 // 它应该在 Data 或 Device 模块中实现 // 并以多态方式传递。 LoginUseCase(this._authenticationRepository); // 由于参数类型是 void,`_` 忽略参数。根据模板中使用的类型进行更改。 Future<Stream<void>> buildUseCaseStream(params) async { final StreamController controller = StreamController(); try { // 假设你在这里传递凭证 await _authenticationRepository.authenticate(email: params.email, password: params.password); logger.finest('LoginUseCase 成功。'); // 触发 onComplete controller.close(); } catch (e) { print(e); logger.severe('LoginUseCase 失败。'); // 触发 .onError controller.addError(e); } return controller.stream; } } ```dart class LoginUseCaseParams { final String email; final String password; LoginUseCaseParams(this.email, this.password); }
后台 UseCase

可以使用 BackgroundUseCase 类在单独的 isolate 上运行用例。 由于 isolate 的限制,实现这种用例与常规用例略有不同。 要创建 BackgroundUseCase,只需扩展该类并重写 buildUseCaseTask 方法。 此方法应返回 UseCaseTask,它只是一个返回类型为 void 且接受 BackgroundUseCaseParameters 参数的函数。 此方法应为静态方法,并将包含您希望在单独的 isolate 上运行的所有代码。此方法应使用 BackgroundUseCaseParameters 中提供的 port 与主 isolate 通信,如下所示。这个例子是执行矩阵乘法的 BackgroundUseCase

class MatMulUseCase extends BackgroundUseCase<List<List<double>>, MatMulUseCaseParams> { // 必须重写 buildUseCaseTask() { return matmul; // 返回包含要在 isolate 上运行的代码的静态方法 } /// 此方法将在单独的 isolate 上执行。[params] 包含所有数据和所需的 sendPort static void matmul(BackgroundUseCaseParams params) async { MatMulUseCaseParams matMulParams = params.params as MatMulUseCaseParams; List<List<double>> result = List<List<double>>.generate( 10, (i) => List<double>.generate(10, (j) => 0)); for (int i = 0; i < matMulParams.mat1.length; i++) { for (int j = 0; j < matMulParams.mat1.length; j++) { for (int k = 0; k < matMulParams.mat1.length; k++) { result[i][j] += matMulParams.mat1[i][k] * matMulParams.mat2[k][j]; } } } // 将结果发送回主 isolate // 这将转发给观察者监听器 params.port.send(BackgroundUseCaseMessage(data: result)); } }

与常规 [UseCase] 一样,建议为任何 [BackgroundUseCase] 使用参数类。 与上面示例对应的示例如下

class MatMulUseCaseParams { List<List<double>> mat1; List<List<double>> mat2; MatMulUseCaseParams(this.mat1, this.mat2); MatMulUseCaseParams.random() { var size = 10; mat1 = List<List<double>>.generate(size, (i) => List<double>.generate(size, (j) => i.toDouble() * size + j)); mat2 = List<List<double>>.generate(size, (i) => List<double>.generate(size, (j) => i.toDouble() * size + j)); } }

领域中的仓库

abstract class AuthenticationRepository { Future<void> register( { String firstName, String lastName, String email, String password}); /// 使用 [username] 和 [password] 对用户进行身份验证 Future<void> authenticate( { String email, String password}); /// 返回 [User] 是否已通过身份验证。 Future<bool> isAuthenticated(); /// 返回当前已验证的 [User]。 Future<User> getCurrentUser(); /// 重置 [User] 的密码 Future<void> forgotPassword(String email); /// 注销 [User] Future<void> logout(); }

此仓库应在数据层中实现

class DataAuthenticationRepository extends AuthenticationRepository { // 单例 static DataAuthenticationRepository _instance = DataAuthenticationRepository._internal(); DataAuthenticationRepository._internal(); factory DataAuthenticationRepository() => _instance; Future<void> register( { String firstName, String lastName, String email, String password}) { // 待实现 } /// 使用 [username] 和 [password] 对用户进行身份验证 Future<void> authenticate( { String email, String password}) { // 待实现 } /// 返回 [User] 是否已通过身份验证。 Future<bool> isAuthenticated() { // 待实现 } /// 返回当前已验证的 [User]。 Future<User> getCurrentUser() { // 待实现 } /// 重置 [User] 的密码 Future<void> forgotPassword(String email) { // 待实现 } /// 注销 [User] Future<void> logout() { // 待实现 } }

如果仓库与平台相关,请在设备层中实现。

实体

领域层中定义。

class User { final String name; final String email; final String uid; User(this.name, this.email, this.uid); }

此处查看一个小示例,在此处查看构建的完整应用程序。

作者

Shady Boukhary Rafael Monteiro

编辑推荐精选

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

Hunyuan3D-2

Hunyuan3D-2

高分辨率纹理 3D 资产生成

Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。

3FS

3FS

一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。

3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等多个模块。它支持多种文件操作,如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。

下拉加载更多