Skip to content

第13章:Dart 模块化与库(工程化基础)

13.1 模块化概述

什么是模块化?

模块化是将代码按照功能或逻辑划分为多个独立的模块,每个模块负责特定的功能。模块化可以提高代码的可维护性、可重用性和可读性。

模块化的优点

  • 代码复用:可以在多个项目中重用模块
  • 可维护性:模块之间相互独立,修改一个模块不会影响其他模块
  • 可读性:代码结构清晰,便于理解和调试
  • 并行开发:多个开发者可以同时开发不同的模块

Dart 中的模块化

在 Dart 中,模块化主要通过库(library)来实现。每个 Dart 文件默认都是一个库,也可以通过 library 关键字显式声明一个库。

13.2 库的导入与使用

导入系统库

Dart 提供了一些内置的系统库,如 dart:coredart:iodart:async 等。这些库可以直接导入使用。

dart
import 'dart:core'; // 导入核心库
import 'dart:io'; // 导入输入输出库
import 'dart:async'; // 导入异步库

导入自定义库

可以导入自己创建的库文件,使用相对路径或绝对路径。

dart
// 导入同一目录下的库
import 'utils.dart';

// 导入子目录下的库
import 'models/user.dart';

// 导入父目录下的库
import '../helpers/date.dart';

导入第三方库

可以从 pub.dev 仓库导入第三方库,需要在 pubspec.yaml 文件中声明依赖,然后使用 pub get 命令安装。

yaml
# pubspec.yaml
dependencies:
  http: ^1.0.0
  flutter: 
    sdk: flutter
dart
// 导入第三方库
import 'package:http/http.dart' as http;

13.3 库的导出

导出单个库

可以使用 export 关键字导出一个库,使得其他文件可以通过导入这个库来访问被导出的库。

dart
// utils.dart
export 'math_utils.dart';
export 'string_utils.dart';
export 'date_utils.dart';

导出部分内容

可以使用 showhide 关键字来控制导出的内容。

dart
// utils.dart
export 'math_utils.dart' show add, subtract;
// 只导出 math_utils.dart 中的 add 和 subtract 函数

export 'string_utils.dart' hide capitalize;
// 导出 string_utils.dart 中除了 capitalize 以外的所有内容

13.4 命名空间

使用 as 关键字

当导入的库中有同名的函数或类时,可以使用 as 关键字为库指定一个前缀,避免命名冲突。

dart
import 'package:http/http.dart' as http;
import 'package:xml/xml.dart' as xml;

void main() {
  // 使用 http 前缀访问 http 库中的函数
  var response = await http.get(Uri.parse('https://example.com'));
  
  // 使用 xml 前缀访问 xml 库中的函数
  var document = xml.XmlDocument.parse(response.body);
}

导入部分内容

可以使用 showhide 关键字来控制导入的内容,减少命名冲突的可能性。

dart
// 只导入 math_utils.dart 中的 add 和 subtract 函数
import 'math_utils.dart' show add, subtract;

// 导入 string_utils.dart 中除了 capitalize 以外的所有内容
import 'string_utils.dart' hide capitalize;

13.5 实操案例

拆分代码为多个模块

1. 创建工具类模块

dart
// utils/math_utils.dart
int add(int a, int b) {
  return a + b;
}

int subtract(int a, int b) {
  return a - b;
}

int multiply(int a, int b) {
  return a * b;
}

double divide(int a, int b) {
  if (b == 0) {
    throw ArgumentError('Division by zero');
  }
  return a / b;
}
dart
// utils/string_utils.dart
String capitalize(String str) {
  if (str.isEmpty) return str;
  return str[0].toUpperCase() + str.substring(1);
}

String reverse(String str) {
  return str.split('').reversed.join();
}

bool isPalindrome(String str) {
  return str == reverse(str);
}

2. 创建导出文件

dart
// utils/utils.dart
export 'math_utils.dart';
export 'string_utils.dart';

3. 在主文件中使用

dart
// main.dart
import 'utils/utils.dart';

void main() {
  // 使用 math_utils.dart 中的函数
  print('1 + 2 = ${add(1, 2)}');
  print('5 - 3 = ${subtract(5, 3)}');
  print('2 * 4 = ${multiply(2, 4)}');
  print('10 / 2 = ${divide(10, 2)}');
  
  // 使用 string_utils.dart 中的函数
  print('Capitalize: ${capitalize('hello')}');
  print('Reverse: ${reverse('hello')}');
  print('Is palindrome "level": ${isPalindrome('level')}');
  print('Is palindrome "hello": ${isPalindrome('hello')}');
}

实现库的导入与导出

1. 创建模型类

dart
// models/user.dart
class User {
  final String id;
  final String name;
  final String email;
  
  User({required this.id, required this.name, required this.email});
  
  @override
  String toString() {
    return 'User(id: $id, name: $name, email: $email)';
  }
}
dart
// models/product.dart
class Product {
  final String id;
  final String name;
  final double price;
  
  Product({required this.id, required this.name, required this.price});
  
  @override
  String toString() {
    return 'Product(id: $id, name: $name, price: $price)';
  }
}

2. 创建导出文件

dart
// models/models.dart
export 'user.dart';
export 'product.dart';

3. 创建服务类

dart
// services/api_service.dart
import 'dart:convert';
import 'dart:io';
import '../models/models.dart';

class ApiService {
  final HttpClient _client = HttpClient();
  
  Future<List<User>> getUsers() async {
    var url = Uri.parse('https://jsonplaceholder.typicode.com/users');
    var request = await _client.getUrl(url);
    var response = await request.close();
    
    if (response.statusCode != HttpStatus.ok) {
      throw Exception('Failed to get users');
    }
    
    var responseBody = await response.transform(utf8.decoder).join();
    var jsonList = jsonDecode(responseBody) as List;
    
    return jsonList.map((json) => User(
      id: json['id'].toString(),
      name: json['name'],
      email: json['email'],
    )).toList();
  }
  
  Future<List<Product>> getProducts() async {
    var url = Uri.parse('https://fakestoreapi.com/products');
    var request = await _client.getUrl(url);
    var response = await request.close();
    
    if (response.statusCode != HttpStatus.ok) {
      throw Exception('Failed to get products');
    }
    
    var responseBody = await response.transform(utf8.decoder).join();
    var jsonList = jsonDecode(responseBody) as List;
    
    return jsonList.map((json) => Product(
      id: json['id'].toString(),
      name: json['title'],
      price: json['price'].toDouble(),
    )).toList();
  }
  
  void close() {
    _client.close();
  }
}

4. 在主文件中使用

dart
// main.dart
import 'services/api_service.dart';

void main() async {
  var apiService = ApiService();
  
  try {
    print('Fetching users...');
    var users = await apiService.getUsers();
    print('Users: ${users.take(3)}'); // 只打印前3个用户
    
    print('\nFetching products...');
    var products = await apiService.getProducts();
    print('Products: ${products.take(3)}'); // 只打印前3个产品
  } catch (e) {
    print('Error: $e');
  } finally {
    apiService.close();
  }
}

13.6 模块化最佳实践

1. 合理划分模块

根据功能或逻辑合理划分模块,每个模块负责特定的功能。

2. 保持模块的独立性

模块之间应该保持独立,通过明确的接口进行通信,避免模块之间的紧密耦合。

3. 使用命名空间

使用 as 关键字为库指定前缀,避免命名冲突。

4. 控制导入和导出的内容

使用 showhide 关键字控制导入和导出的内容,减少不必要的依赖。

5. 文档注释

为模块和公共 API 添加文档注释,提高代码的可读性和可维护性。

6. 版本控制

对于第三方库,指定明确的版本范围,避免版本冲突。

小结

  • 模块化 是将代码按照功能或逻辑划分为多个独立的模块,提高代码的可维护性、可重用性和可读性。
  • 库的导入与使用:可以导入系统库、自定义库和第三方库。
  • 库的导出:使用 export 关键字导出库,使得其他文件可以通过导入这个库来访问被导出的库。
  • 命名空间:使用 as 关键字为库指定前缀,避免命名冲突。
  • 模块化最佳实践:合理划分模块、保持模块的独立性、使用命名空间、控制导入和导出的内容、添加文档注释、版本控制等。

通过掌握模块化和库的使用,你可以编写更结构化、更可维护的 Dart 代码,提高开发效率。

© 2026 编程马·菜鸟教程 版权所有