对我来说有两种情况,要么函数描述了其输入,调用者必须以正确的形状提供它们,要么函数利用了现有的应用程序实体(数据模型),应通过名称引用其定义。
在函数不操作实体的情况下,我确保有良好的参数名,描述形状在文档字符串中,如果获取映射或元组则使用解构每个元素命名。有时我也可能有一个规范,但这只有在我想也使用它进行生成测试或对其进行验证时才是如此。
在函数操作实体的情况下,我将参数名与实体定义的名称相同。
我通过构造函数定义我的实体,一个名为make-foo的函数创建foo类型实体的实例。该函数将描述其创建的形状,或者从其代码中很容易识别人工智能。或者我使用记录定义它们,记录定义描述了形状。或者我使用规范定义它们,规范名称与实体名称相同。
(defn make-item
"Makes an item which is a map of key
:id UUID of the todo-list
:name - the user readable string name of the item
:content - the user provided string content of the item"
[name content]
{:id (java.util.UUID/randomUUID)
:name name
:content content})
(defn make-todo-list
"Makes a todo-list which is a map of key
:id - UUID of the todo-list
:name - the user readable string name of the list
:items - an ordered vector of item"
[name & items]
{:id (java.util.UUID/randomUUID)
:name name
:items (vec items)})
(defn insert-item
"Inserts an item in a todo-list at given 0-based position"
[todo-list item position]
(apply conj
(subvec todo-list 0 position)
item
(subvec todo-list position (count todo-list))))
(defn sanitize-input
"Given an untrusted input string, return a sanitized version.
Takes an optional options map with options:
:extra-denylist - a seq of string words to delete on top of default sanitization."
[input-string & {:keys [extra-denylist] :as options}]
(some-lib/sanitize input-string extra-denylist)
所以,正如你在我的小例子中看到的那样,sanitize-input
是一个不操作应用程序领域模型的函数示例,所以它仅使用良好的参数名称、解构和优秀的文档字符串来描述其输入。
另一方面,insert-item
是一个操作应用程序领域模型的函数,所以它仅使用其输入领域实体的相同名称,额外的参数位置
由良好的名称和文档字符串描述。
最后,域实体通过各自名称的 make-
函数进行描述。我也可以使用记录或者规范(Spec)来代替。