验证用户名的代码
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上面代码的缺点:在其他地方使用会重复``` swiftextension 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的区别
// 有一个满足就为truefunc contains(where predicate: (Element) throws -> Bool) rethrows -> Bool// 所以满足就为truefunc allSatisfy(_ predicate: (Element) throws -> Bool) rethrows -> Bool复制代码
参考: