介绍
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个协议。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
实现
步骤 1
定义一个协议
protocol InputValidator {
func validateInput(inputText: String) -> Bool
}
步骤 2
创建一个UITextField的子类
class ValidTextField: UITextField {
var inputValidator: InputValidator?
@discardableResult
func validate(inputText: String) -> Bool {
if let inputValidator = inputValidator {
return inputValidator.validateInput(inputText: inputText)
}
return false
}
}
步骤 3
创建实现协议的具体类
class EmailValidator: InputValidator {
func validateInput(inputText: String) -> Bool {
let pattern = "^([a-zA-Z0-9]+([._\\-])*[a-zA-Z0-9]*)+@([a-zA-Z0-9])+(.([a-zA-Z])+)+$"
let regular = try? NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive)
let matches = regular?.matches(in: inputText, range: NSRange(location: 0, length: inputText.count))
return matches?.count ?? 0 > 0
}
}
class PhoneValidator: InputValidator {
func validateInput(inputText: String) -> Bool {
let pattern = "^1[0-9]{10}$"
let regular = try? NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive)
let matches = regular?.matches(in: inputText, range: NSRange(location: 0, length: inputText.count))
return matches?.count ?? 0 > 0
}
}
步骤 4
使用
class ViewController: UIViewController, UITextFieldDelegate {
var emailTextField : ValidTextField?
var phoneTextField : ValidTextField?
override func viewDidLoad() {
super.viewDidLoad()
//邮箱输入框
let emailTextField = ValidTextField()
self.emailTextField = emailTextField
emailTextField.inputValidator = EmailValidator()
emailTextField.backgroundColor = UIColor.brown
emailTextField.frame = CGRect(x: 10, y: 100, width: 300, height: 44)
emailTextField.delegate = self
self.view.addSubview(emailTextField)
//手机号输入框
let phoneTextField = ValidTextField()
self.phoneTextField = phoneTextField
phoneTextField.inputValidator = PhoneValidator()
phoneTextField.backgroundColor = UIColor.brown
phoneTextField.frame = CGRect(x: 10, y: 160, width: 300, height: 44)
phoneTextField.delegate = self
self.view.addSubview(phoneTextField)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
self.emailTextField?.resignFirstResponder()
self.phoneTextField?.resignFirstResponder()
}
func textFieldDidEndEditing(_ textField: UITextField) {
if let textField = textField as? ValidTextField {
if textField.inputValidator is EmailValidator {
let isEmail = textField.validate(inputText: textField.text ?? "")
print(isEmail ? "输入的是邮箱": "输入的不是邮箱")
} else if textField.inputValidator is PhoneValidator {
let isPhone = textField.validate(inputText: textField.text ?? "")
print(isPhone ? "输入的是手机号": "输入的不是手机号")
}
}
}
}