dart effective-设计
1.命名
对同一个事物使用相同的名称表示
除非缩写比未缩写的术语更加普遍,否则不要用缩写
优先把描述性强的词语方法最后
pageCount
buildRectangles
IOStream
HttpRequest
考虑把代码读取来像句子一样流畅
// "If errors is empty..." if (errors.isEmpty) ... // "Hey, subscription, cancel!" subscription.cancel(); // "Get the monsters where the monster has claws." monsters.where((monster) => monster.hasClaws);
在非布尔或者变量上,优先使用名词
list.length
context.lineWidth
在布尔值等变量上,优先使用动词
if (window.closeable) ... // Adjective. if (window.canClose) ... // Verb.
布尔值的命名参数,不使用动词更加易读
Isolate.spawn(entryPoint, message, paused: false); var copy = List.from(elements, growable: true); var regExp = RegExp(pattern, caseSensitive: false);
为布尔值命名一个正的逻辑,双重否等不容易理解
//好 if (socket.isConnected && database.hasData) { socket.write(database.read()); } //坏 if (!socket.isDisconnected && !database.isEmpty) { socket.write(database.read()); }
主要目的是动作时,用动词
list.add("element"); queue.removeFirst(); window.refresh();
主要目的是结果时,用名词
var element = list.elementAt(3); var first = list.firstWhere(test); var char = string.codeUnitAt(4);
如果您想引起对函数或方法的注意,请给该成员一个描述该工作的动词短语名称
var table = database.downloadData(); var packageVersions = packageGraph.solveConstraints();
复制到新对象 使用to__()
list.toSet();
stackTrace.toString();
dateTime.toLocal();
复制到新对象使用as__()
var map = table.asMap(); var list = bytes.asFloat32List(); var future = subscription.asFuture();
避免函数中描述参数
//好 list.add(element); map.remove(key); //坏 list.addElement(element) map.removeKey(key)
类型要遵守助记符约定
//E对于集合中的元素类型: class IterableBase<E> {} class List<E> {} class HashSet<E> {} class RedBlackTree<E> {}
//K以及关联集合中V的键和值类型: class Map<K, V> {} class Multimap<K, V> {} class MapEntry<K, V> {}
//R用于用作函数或类的方法的返回类型的类型,不常见,但有时会出现在typedef中以及实现访问者模式的类中: abstract class ExpressionVisitor<R> { R visitBinary(BinaryExpression node); R visitLiteral(LiteralExpression node); R visitUnary(UnaryExpression node); }
//请对具有单个类型参数且泛型类型使其含义显而易见的泛型使用T,S和U。这里有多个字母,以允许嵌套而不遮盖周围的名称。例如: class Future<T> { Future<S> then<S>(FutureOr<S> onValue(T value)) => ... }
//如果以上情况都不适合,则可以使用另一个单字母助记符名称或描述性名称: class Graph<N, E> { final List<N> nodes = []; final List<E> edges = []; } class Graph<Node, Edge> { final List<Node> nodes = []; final List<Edge> edges = []; }
2.库
优先将生命设置为私有
考虑在同一个库中声明多个类
3.类和混合
4.构造函数
5.成员
6.类型
7.参数
函数参数是bool时,使用命名参数可以易读
Task.oneShot(); Task.repeating(); ListBox(scroll: true, showScrollbars: true); Button(ButtonState.enabled);
如果用户可能想省略较早的参数,请避免使用可选的位置参数。
String.fromCharCodes(Iterable<int> charCodes, [int start = 0, int end]);
避免接受强制性参数,该参数接受特殊的“无参数”值
var rest = string.substring(start);//好 var rest = string.substring(start, null);//坏
不要使用包含开始和包含结束参数来接受范围
使用起始和长度
[0, 1, 2, 3].sublist(1, 3) // [1, 2] 'abcd'.substring(1, 3) // 'bc'
8.相等