MST

星途 面试题库

面试题:Flutter http插件封装在复杂业务场景下的优化与扩展

假设在一个大型Flutter项目中,涉及多种不同类型的网络请求(如文件上传、下载、WebSocket 结合等),以及复杂的业务逻辑(如根据不同用户角色调整请求参数),请详细说明如何对http插件的封装进行优化与扩展,以适应这样的复杂场景,包括架构设计、性能优化、代码结构组织等方面。
14.9万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

架构设计

  1. 分层架构
    • 数据层:负责与网络进行交互,封装http请求细节。在此层创建HttpService类,使用httpdio插件处理具体的HTTP请求。例如:
class HttpService {
  final Dio _dio = Dio();

  Future<Response> uploadFile(String url, FormData formData) async {
    return _dio.post(url, data: formData);
  }

  Future<Response> downloadFile(String url, String savePath) async {
    return _dio.download(url, savePath);
  }
}
- **业务逻辑层**:根据不同用户角色调整请求参数。创建`RequestBuilder`类,负责构建请求。例如:
class RequestBuilder {
  static Map<String, dynamic> buildParams(UserRole role) {
    if (role == UserRole.admin) {
      return {'role': 'admin', 'extra_param': 'admin_only'};
    } else {
      return {'role': 'user'};
    }
  }
}
- **表现层**:调用业务逻辑层和数据层方法发起请求。在页面或视图模型中调用上述方法。

2. 依赖注入 使用providerget_it等依赖注入库,将HttpService等实例注入到需要的地方,提高代码的可测试性和可维护性。例如,使用get_it

final getIt = GetIt.instance;
getIt.registerSingleton<HttpService>(HttpService());

在需要使用的地方:

final httpService = getIt<HttpService>();

性能优化

  1. 缓存策略 对于一些不经常变化的数据请求,设置缓存机制。可以使用dioCacheManager。例如:
var cacheManager = CacheManager(
  Config(
    'my_cache_key',
    maxStale: const Duration(days: 7),
  ),
);
_dio.interceptors.add(cacheManager.interceptor);
  1. 并发请求管理 对于多个网络请求,可以使用Future.wait进行并发处理,但要注意资源消耗。例如:
List<Future<Response>> requests = [
  httpService.fetchData1(),
  httpService.fetchData2()
];
List<Response> responses = await Future.wait(requests);
  1. 优化网络请求
    • 压缩请求和响应数据,在dio中可以通过设置options启用gzip压缩:
_dio.options = BaseOptions(
  headers: {'Accept-Encoding': 'gzip'},
);
- 合理设置请求超时时间,避免长时间等待:
_dio.options.connectTimeout = 5000; // 5 seconds
_dio.options.receiveTimeout = 3000; // 3 seconds

代码结构组织

  1. 模块化 将不同类型的网络请求封装到不同的文件中。例如,file_requests.dart处理文件上传下载,websocket_requests.dart处理WebSocket相关请求。
  2. 错误处理HttpService中统一处理网络错误。例如:
Future<Response> sendRequest(RequestOptions options) async {
  try {
    return await _dio.request(options);
  } on DioError catch (e) {
    if (e.response != null) {
      // 处理HTTP错误
      print('HTTP error: ${e.response.statusCode}');
    } else {
      // 处理其他错误,如连接超时
      print('Error: ${e.message}');
    }
    throw e;
  }
}
  1. 日志记录 添加日志记录功能,方便调试和排查问题。可以使用logger库:
import 'package:logger/logger.dart';
final logger = Logger();

Future<Response> sendRequest(RequestOptions options) async {
  logger.i('Sending request to ${options.path}');
  try {
    return await _dio.request(options);
  } catch (e) {
    logger.e('Request failed: $e');
    throw e;
  }
}