Как инициализировать класс в течение нескольких контроллеров представления

#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 методами, в которых они отказались бы принимать значение, если бы это значение уже было установлено, и так далее. Также я думаю, что вы могли бы использовать ключевые пути каким-то образом, чтобы сделать код аккуратнее/меньше.