#swift #xcode #class #optional
Вопрос:
У меня есть Event
класс, в котором есть такие переменные, как Date
, Time
Activity
, и т. Д. Пользователь может создать Event
с помощью ряда контроллеров представления, которые позволяют пользователю создавать его по одной переменной за раз, что-то вроде пошагового руководства. Моя проблема заключается в том, что для инициализации Event
на первом экране я использую пустой инициализатор, и все переменные экземпляра по умолчанию являются необязательными. Когда пользователь проходит по экранам, они настраиваются соответствующим образом. Как бы я правильно инициализировал этот класс с течением времени? Использование дополнительных параметров для всех переменных кажется неправильным.
Я хотел бы инициализировать Event
на первом экране, как это:
var event = Event()
И установите переменные экземпляра один за другим, чтобы все они не были необязательными.
Комментарии:
1. «Я хотел бы инициализировать…» Нет. Вы не можете инициализировать класс с течением времени. Вы можете задать свойства экземпляра с течением времени. В таком случае то, что вы делаете, кажется прекрасным. Не волнуйся, будь счастлива.
2. Однако в качестве альтернативы вы можете продолжать вызывать конструктор, который создает событие полностью сформированным только после предоставления всей необходимой информации.
3. @matt как бы работала такая функция строителя? Как бы это добавляло одно и то же событие при каждом вызове? Или переменные все равно должны быть необязательными?
4. Не имеет значения, какова переменная Конструктора, потому что они будут частными. Это просто функции: функции ввода, чтобы клиенты могли предоставлять информацию, и функция вывода, чтобы Конструктор мог предоставить полностью сформированное событие. Дело в том, что в этой модели Событию не нужны никакие дополнительные свойства, потому что Конструктор не создает его экземпляр, пока не получит всю информацию.
Ответ №1:
Вы не можете инициализировать класс с течением времени. Вы можете задать свойства экземпляра с течением времени. В таком случае то, что вы делаете, кажется прекрасным. Однако в качестве альтернативы вы можете продолжать вызывать конструктор, который создает событие полностью сформированным только после предоставления всей необходимой информации. Представьте себе такую архитектуру (попробуйте ее на своей игровой площадке).:
class Event : CustomStringConvertible {
let fee : String
let fi : String
let fo : String
let fum : String
init(fee:String, fi:String, fo:String, fum:String) {
self.fee = fee; self.fi = fi; self.fo = fo; self.fum = fum
}
var description : String {
"Event: (fee) (fi) (fo) (fum)"
}
}
class EventBuilder {
private var fee : String?
private var fi : String?
private var fo : String?
private var fum : String?
private var event : Event?
private func makeEventIfPossible() {
guard event == nil else {return}
if let fee = fee,
let fi = fi,
let fo = fo,
let fum = fum {
print("making event")
self.event = Event(fee: fee, fi: fi, fo: fo, fum: fum)
}
}
func takeFee(_ fee:String) {
self.fee = fee
makeEventIfPossible()
}
func takeFi(_ fi:String) {
self.fi = fi
makeEventIfPossible()
}
func takeFo(_ fo:String) {
self.fo = fo
makeEventIfPossible()
}
func takeFum(_ fum:String) {
self.fum = fum
makeEventIfPossible()
}
func giveEvent() -> Event? {
self.event
}
}
let b = EventBuilder()
b.takeFee("Fee")
b.takeFi("Fi")
b.takeFo("Fo")
b.takeFum("Fum")
if let event = b.giveEvent() {
print(event) // and away we go
}
Вы можете передать EventBuilder, разные объекты могут вызывать разные take
методы, и никто не сможет получить событие, giveEvent
пока не будет предоставлена вся информация и событие не будет создано. Как вы можете видеть, событие создается только один раз, и ни одно из его свойств не является необязательным. Конструктор скрывает весь процесс создания за функциональным представлением (отсюда и название).
Я могу представить дальнейшие уточнения, например, вы могли бы сделать take
методы throws
методами, в которых они отказались бы принимать значение, если бы это значение уже было установлено, и так далее. Также я думаю, что вы могли бы использовать ключевые пути каким-то образом, чтобы сделать код аккуратнее/меньше.