Допустим, у меня есть цветовая модель:
protocol Color {
var value: String? { get }
}
class UnknownColor: Color {
let value: String? = nil
}
class KnownColor: Color {
let value: String?
init(value: String? = nil) {
self.value = value
}
}
В моем файле вида я добавляю некоторые детали вида в мою модель цвета.
Эти детали не зависят от модели, а от вида.
fileprivate extension Color {
fileprivate var representation: String {
return self.value!
}
}
fileprivate extension UnknownColor {
fileprivate var representation: String {
return "#000"
}
}
Теперь, когда я использую свою цветовую модель в файле вида, я ожидаю, что мои UnknownColor
s будут представлять себя как "#000"
, но это не тот случай, когда UnknownColor
приводится как Color
.
let color1 = KnownColor()
let color2 = KnownColor(value:"#fff")
let color3 = UnknownColor()
color1.representation // Fatal error (GOOD)
color2.representation // "#fff" (GOOD)
color3.representation // "#000" (GOOD)
if let color = color3 as? Color {
color.representation // Fatal error (BAD, expected "#000")
}
Я хочу избежать явной проверки типов для UnknownColor
, поэтому подобное решение не является идеальным:
func colorRepresentation(_ color: Color) {
if let color = color as? UnknownColor {
return "#000"
} else {
return color.value!
}
}
Я хочу избежать любых изменений в модели Color любой ценой.
Может быть много реализаций протокола Color
, которые хотят использовать Color.representation
, поэтому изменение extension Color
на extension KnownColor
не вариант.
Есть ли способ, которым я могу реструктурировать свой код так, чтобы UnknownColor.representation
использовался, когда Color
на самом деле UnknownColor
?