如何在Dart中使用Extension
写出干净整洁的代码?
在我的Flutter项目中,我经常使用Enum,但是集成Enum
和Extension
方法会让代码变得更简洁易读。
假设你写了一个Enum,然后你根据这个Enum的值返回不同的显示文本。在以前,会使用IIFE(media post)widget
中使用switch
语句,在函数表达式中调用匿名方法,虽然在Dart中这很常用,但这种模式会产生很多面条式代码,如下例所示。另外,如果需要在其他地方添加相同的文本,则必须复制整个代码片段,而不是仅仅进行函数调用,存在大量的重复代码。
Text((){
switch (selectedColor) {
case SelectedColor.PrimaryColor:
return 'This is the Primary Color';
case SelectedColor.SecondaryColor:
return 'This is the Secondary Color';
default:
return 'SelectedScheme Title is null';
}
}()),
Text((){
switch (selectedColor) {
case SelectedColor.PrimaryColor:
return 'This is the Primary Color';
case SelectedColor.SecondaryColor:
return 'This is the Secondary Color';
default:
return 'SelectedScheme Title is null';
}
}()),
enum SelectedColor {
primaryColor,
secondColor,
}
extension SelectedColorExtension on SelectedColor {
String get name => describeEnum(this);
String get displayTitle {
switch (this) {
case SelectedColor.primaryColor:
return 'This is the Primary Color';
case SelectedColor.secondColor:
return 'This is the Secondary Color';
default:
return 'SelectedScheme Title is null';
}
}
String get displayColorChangeText {
switch (this) {
case SelectedColor.primaryColor:
return 'Change to Secondary Color';
case SelectedColor.secondColor:
return 'Change to Primary Color';
default:
return 'SelectedScheme is null';
}
}
String describeEnum(Object enumEntry) {
final String description = enumEntry.toString();
final int indexOfDot = description.indexOf('.');
assert(indexOfDot != -1 && indexOfDot < description.length - 1);
LogUtils().e(description.substring(indexOfDot + 1));
return description.substring(indexOfDot + 1);
}
Color color() {
switch (this) {
case SelectedColor.primaryColor:
return Colors.red;
case SelectedColor.secondColor:
return Colors.blue;
default:
return Colors.transparent;
}
}
}
现在,你不用为此而烦恼,你只需要扩展你的Enum
并实现一个扩展方法就可以搞定这一切。使用这种方式可以实现相同的功能,并且代码更简洁易读。
Flutter Foundation
中定义的describeEnum()
函数从enumEntry.toString()
返回值中中剥离了枚举类名,仅返回了枚举值的字符串。我提供了一个自定义的替代实现,你可以将它用于其他Dart
项目。
在示例代码中,我给枚举扩展了一个方法displayTitle()
,。当调用displayTitle()
方法时,你会发现明显比IIFE更模块化,更简洁,更新枚举添加新枚举值也会变得更加容易,添加新的扩展方法也非常容易。
enum HomeItemType {
approval, //业务审批
report, //数据报表
work, //工作交流
board, //数据看板
feedback, //问题反馈
announce, //公告公示
}
extension HomeItemTypeExtension on HomeItemType {
String get name => describeEnum(this);
String get displayTitle {
switch (this) {
case HomeItemType.approval:
return '业务审批';
case HomeItemType.report:
return '数据报表';
case HomeItemType.work:
return '工作交流';
case HomeItemType.board:
return '数据看板';
case HomeItemType.feedback:
return '问题反馈';
case HomeItemType.announce:
return '公告公示';
default:
return 'Title is null';
}
}
String get displayImage {
switch (this) {
case HomeItemType.approval:
return 'assets/images/home_approval.png';
case HomeItemType.report:
return 'assets/images/home_report.png';
case HomeItemType.work:
return 'assets/images/home_work.png';
case HomeItemType.board:
return 'assets/images/home_board.png';
case HomeItemType.feedback:
return 'assets/images/home_feedback.png';
case HomeItemType.announce:
return 'assets/images/home_announce.png';
default:
return 'image is null';
}
}
String describeEnum(Object enumEntry) {
final String description = enumEntry.toString();
final int indexOfDot = description.indexOf('.');
assert(indexOfDot != -1 && indexOfDot < description.length - 1);
LogUtils().e(description.substring(indexOfDot + 1));
return description.substring(indexOfDot + 1);
}
}