我想创建一个具有两个属性的Validatable
协议:一个validator
和一个isAbleToProceed
布尔值:
protocol Validatable {
var validator: Validator { get set }
var isAbleToProceed: Bool { get set }
}
我想定义Validators
的不同类型(出生验证器日期,电子邮件验证器等)。为此,我创建了一个工厂:
protocol Validator {}
struct ValidatorFactory {
internal static let sharedInstance = ValidatorFactory()
func dateOfBirthValidator(minimumAge: Int, maximumAge: Int) -> DateOfBirthValidator {
return DateOfBirthValidator(minimumAge: minimumAge, maximumAge: maximumAge)
}
func driversLicenseValidator(minLicenseDuration: Int) -> DriversLicenseValidator {
return DriversLicenseValidator(minLicenseDuration: minLicenseDuration)
}
}
这是DateOfBirthValidator的实现:
struct DateOfBirthValidator: Validator {
let minimumAge: Int
let maximumAge: Int
func isDateOfBirthValid(date: Date) -> Bool {
if let age = Calendar.current.dateComponents([.year], from: date, to: Date()).year {
return (minimumAge ... maximumAge).contains(age)
} else {
return false
}
}
}
然后我将有一个类ViewController来实现Validatable协议:
class ViewController: Validatable {
// MARK: Internal Properties
internal var validator: DriversLicenseValidator
internal var isAbleToProceed: Bool = false
}
但是编译器会报告ViewController不符合
Validatable
(没有验证器)
如果我使Validator
成为超类并且所有验证器结构都变为类并从中继承,则可以解决此问题。但是有办法使它与结构和协议一起工作吗?
答案 0 :(得分:2)
This question几乎是您的副本,只是它询问为什么不能通过协议一致性来满足仅获取属性。答案是,理论上可以,但是现在您不能。上面有几个Swift错误
现在,在您的情况下,您具有get / set属性(至少按照协议中的声明;您在实现中将其设置为let
)。
由于Liskov替代原则,我应该可以说:
var someValidatable = ViewController() as Validatable
someValidateable.validator = SocialSecurityValidator()
如果您能够做自己想做的事,则失败的原因有两个:
validator
的访问权限受到限制,并且是let
而不是var
SocialSecurityValidator
分配给validator
,因为它的类型为DriversLicenseValidator