Flutter代码优化插件guard_clauses的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter代码优化插件guard_clauses的使用


coverage   build

Guard Clauses

这是一个 Dart 版本的 Ardalis 的 C# Guard Clauses 包。它是一个简单的可扩展包,包含 Guard Clauses 扩展。

Guard Clauses 是一种软件模式,通过“快速失败”来简化复杂函数,提前检查无效输入,并立即在发现任何无效输入时失败。

使用方法

void processOrder(Order? order)
{
    Guard.against.nullValue(order, 'order');

    // 处理订单
}

// 或者

class Order
{
    String _name;
    int _quantity;
    double _max;
    double _unitPrice;

    Order(String name, int quantity, double max, double unitPrice) {
        _name = Guard.against.nullOrWhiteSpace(name);
        _quantity = Guard.against.negativeOrZero(quantity);
        _max = Guard.against.zero(max);
        _unitPrice = Guard.against.negative(unitPrice);
    }
}

支持的 Guard Clauses

  • Guard.against.invalidInput(如果谓词表达式返回 false,则抛出异常)
  • Guard.against.invalidFormat(如果输入字符串不匹配提供的正则表达式,则抛出异常)
  • Guard.against.negative(如果输入为负数,则抛出异常)
  • Guard.against.negativeOrZero(如果输入为负数或零,则抛出异常)
  • Guard.against.nullValue(如果输入为 null,则抛出异常)
  • Guard.against.nullOrEmpty(如果字符串输入为 null 或空,则抛出异常)
  • Guard.against.nullOrEmptyCollection(如果输入集合为 null 或空,则抛出异常)
  • Guard.against.nullOrWhiteSpace(如果字符串输入为 null、空或空白,则抛出异常)
  • Guard.against.nullOrInvalidInput(如果输入为 null,或者谓词表达式返回 false,则抛出异常)
  • Guard.against.indexOutOfRange(如果输入不是有效索引,则抛出异常)
  • Guard.against.outOfRangeItems(如果输入集合中的任何值超出了提供的范围,则抛出异常)
  • Guard.against.outOfRange(如果输入集合超出提供的范围,则抛出异常)
  • Guard.against.zero(如果数字输入为零,则抛出异常)

自定义 Guard Clauses

要通过创建自己的 Guard Clauses 进行扩展,可以创建一个新的 Guard 扩展类。

extension GuardExtensions on Guard {
  /// 如果 [input] 为 'foo',则抛出 ArgumentError。
  /// 否则返回 [input]。
  String foo(String input, {String? name}) {
    if (input.toLowerCase() == 'foo') {
      throw ArgumentError.value(input, name);
    }

    return input;
  }
}

// 使用
void sumpin(String otherSumpin) {
    Guard.against.foo(otherSumpin);
    ...
}

示例代码

import 'package:guard_clauses/guard_clauses.dart';

/// 表示一个华丽的独角兽。
class Unicorn {
  bool likesCandy = true;
  bool lovesRainbows = true;

  /// 让独角兽摆姿势拍照。
  void pose(int poseDurationInSeconds, String poseDescription) {
    Guard.against.negativeOrZero(poseDurationInSeconds);
    Guard.against.nullOrWhitespace(poseDescription, name: 'poseDescription', message: '必须有值');

    print("独角兽摆姿势 $poseDurationInSeconds 秒的方式是: $poseDescription");
  }

  /// 独角兽吃跳跳糖。
  void eatSkittles(int numSkittles) {
    print('独角兽吃了 ${Guard.against.negative(numSkittles)} 颗美味的跳跳糖');
  }
}

/// 表示一个漂亮的彩虹。
class Rainbow {
  /// 独角兽骑彩虹。
  void ride(Unicorn corn) {
    Guard.against.invalidInput<Unicorn>(corn, (u) => u.lovesRainbows, name: 'corn', message: '必须喜欢彩虹');
    print('独角兽腾空而起,惊人的飞向彩虹');
  }

  /// 更改彩虹的颜色。
  void changeColors(List<String> newColors) {
    Guard.against.nullOrEmptyCollection(newColors);
  }
}

更多关于Flutter代码优化插件guard_clauses的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter代码优化插件guard_clauses的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,guard_clauses(守卫子句)是一种有效的代码优化技术,用于提高代码的可读性和维护性。通过在函数的开头检查各种条件并立即返回,可以减少嵌套层次,使代码更加清晰。

Flutter本身并没有直接提供guard_clauses的插件,但你可以通过重构代码来使用这种技术。以下是一个示例,展示如何在Flutter项目中使用guard_clauses来优化代码。

假设我们有一个函数,用于处理用户输入并返回相应的结果。在没有使用guard_clauses之前,代码可能看起来像这样:

String processUserInput(String input) {
  if (input == null || input.isEmpty) {
    return "Input cannot be null or empty";
  }

  if (input.length > 20) {
    return "Input is too long";
  }

  // Perform some valid processing
  return "Processed input: " + input.toUpperCase();
}

使用guard_clauses优化后的代码:

String processUserInputOptimized(String input) {
  // Guard clause for null or empty input
  if (input == null || input.isEmpty) {
    return "Input cannot be null or empty";
  }

  // Guard clause for input length greater than 20
  if (input.length > 20) {
    return "Input is too long";
  }

  // Main processing logic
  return "Processed input: " + input.toUpperCase();
}

虽然这两个函数的逻辑相同,但优化后的版本通过使用guard_clauses减少了嵌套,使代码更加简洁和易读。

在实际项目中,你可以将这种技术应用于更复杂的逻辑。例如,在一个Flutter Widget中处理用户输入并进行验证:

class UserInputScreen extends StatefulWidget {
  @override
  _UserInputScreenState createState() => _UserInputScreenState();
}

class _UserInputScreenState extends State<UserInputScreen> {
  final TextEditingController _controller = TextEditingController();
  String _result = "";

  void _handleSubmit() {
    String input = _controller.text;

    // Guard clause for null or empty input
    if (input == null || input.isEmpty) {
      setState(() {
        _result = "Input cannot be null or empty";
      });
      return;
    }

    // Guard clause for input length greater than 20
    if (input.length > 20) {
      setState(() {
        _result = "Input is too long";
      });
      return;
    }

    // Main processing logic
    setState(() {
      _result = "Processed input: " + input.toUpperCase();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('User Input Screen'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: <Widget>[
            TextField(
              controller: _controller,
              decoration: InputDecoration(hintText: 'Enter something'),
            ),
            SizedBox(height: 16.0),
            ElevatedButton(
              onPressed: _handleSubmit,
              child: Text('Submit'),
            ),
            SizedBox(height: 16.0),
            Text(_result),
          ],
        ),
      ),
    );
  }
}

在这个例子中,_handleSubmit方法使用了guard_clauses来检查用户输入是否为空或过长,并在这些情况下立即返回,避免了进一步的处理。这样做不仅提高了代码的可读性,还使错误处理更加明确。

回到顶部