验证用户名的代码
func authenticate(user: String) {
// make sure usernames are at least three characters
guard user.trimmingCharacters(in: .whitespacesAndNewlines).count >= 3 else {
print("Username \(user) is too short.")
return
}
// make sure usernames contain no invalid characters
let illegalCharacters = ["@", "-", "&", "."]
guard illegalCharacters.contains(where: user.contains) == false else {
print("Username \(user) contains illegal characters.")
return
}
// Proceed with authentication…
}
``` swift
上面代码的缺点:在其他地方使用会重复
``` swift
extension String {
func isValidUsername() -> Bool {
guard self.trimmingCharacters(in: .whitespacesAndNewlines).count >= 3 else {
return false
}
let illegalCharacters = ["@", "-", "&", "."]
guard illegalCharacters.contains(where: self.contains) == false else {
return false
}
return true
}
}
复制代码
上面代码的缺点:需要在每个地方调用isValidUsername()
struct User: Equatable {
let value: String
init?(string: String) {
guard string.trimmingCharacters(in: .whitespacesAndNewlines).count >= 3 else {
return nil
}
let illegalCharacters = ["@", "-", "&", "."]
guard illegalCharacters.contains(where: string.contains) == false else {
return nil
}
self.value = string
}
}
func authenticate(user: User) {
// Proceed with authentication…
}
复制代码
值对象:value objects should be both immutable and equatable, but they also add in validation as part of their creation. This means that if you’re handed a value object you know for sure it’s already passed validation – you don’t need to re-validate it, because if it were valid then it couldn’t exist.
设计:参考系统的 URL(string: "This ain't it chief")
好处:安全,扩展性强
注:contains与allSatisfy的区别
// 有一个满足就为true
func contains(where predicate: (Element) throws -> Bool) rethrows -> Bool
// 所以满足就为true
func allSatisfy(_ predicate: (Element) throws -> Bool) rethrows -> Bool
复制代码