Проблема шаблона проектирования: при сбоях расширений и протоколов - PullRequest
0 голосов
/ 16 июня 2019

С протоколами вы определяете поведение с заглушками функциональности; но без кода.

С помощью расширений вы добавляете код и поведение для каждого отдельного типа расширяемого вами класса в рамках вашего проекта; даже если некоторые из них не нуждаются или не должны знать о таком коде.

Множественное наследование не существует в Swift.

Итак, что вы делаете, когда у вас есть подмножество всех ваших контроллеров ViewController, которым всем нужно знать, как делать то же самое, и вы не хотите вводить код снова и снова или копировать / вставлять, и все же Расширения означают, что больший набор ViewControllers получает код, который им никогда не нужен или о котором не нужно знать?

Допустим, у меня в небольшом приложении 10 контроллеров вида.

9 из них имеют несколько UITextField для ввода данных.

Из этих 9, 5 из них есть требования к вводу данных, которые являются общими для всех 5, но не общими для всех. например Для 3 из 5 может потребоваться поле «Возраст», но не для всех 5. 4 из них может требовать «Идентификационный номер», а для 5-го - нет.

Итак, из 5 ViewControllers есть 12 отдельных полей ввода данных, которые являются общими для них, но не для каждого из них.

Для всех этих 12 полей ввода данных (UITextFields) может быть написан код, который ограничивает и форматирует данные при их вводе в UITextField, предотвращая неверные данные, например, возраст более 100 или идентификационный номер> количество сотрудников и т. Д.

Вопрос в следующем:

Было бы легко создать Расширение для UIViewController, которое содержало бы все 12 проверок кода проверки поля ввода данных - и это действительно то, что я сделал.

Однако, поскольку эти поля появляются только в 5 из 10 контроллеров представления в моем приложении, все 10 контроллеров представления имеют это расширение.

Так, как мне ограничить это только 5, которые нуждаются в этом?

Мне не нужен код в классе, потому что тогда каждому из них придется создавать свои собственные экземпляры, а это дублирование в памяти.

То же самое для использования структуры.

Единственное решение, которое я могу придумать, это синглтон; но я всегда уклоняюсь от синглетонов, потому что никогда не уверен, оправдано ли их использование.

Ответы [ 2 ]

1 голос
/ 16 июня 2019

Расширение протокола будет делать то, что вы ищете. Используя ваш пример, вы можете получить что-то вроде этого:

protocol ageValidatable {
    func isValidAge(_ age: Int) -> Bool
}

extension ageValidatable {
    func isValidAge(_ age: Int) -> Bool {
        return age > 0 && age < 150
    }
}

Теперь любой ViewController, который реализует ageValidatable, будет иметь реализацию по умолчанию isValidAge без необходимости его определения. Вы можете

  • Переопределите, если вы выберете
  • Дайте это только ViewControllers, которым это требуется
  • Разрешить ViewController соответствовать более чем одному из этих протоколов
  • Создайте typealiases для групп этих протоколов, если вы в конечном итоге соответствуете многим из них. т.е. typealias employeeValidatable = ageValidatable & employeeIDValidatable
0 голосов
/ 16 июня 2019

Строго говоря, с точки зрения MVC, я бы, вероятно, дал бы эту собственную структуру, т. Е. InputValidator, и присвоил бы ее экземпляр свойству ViewController, чтобы у нас не было бизнес-логики непосредственно внутри нашего ViewController.

Даже если вы не пишете эти функции внутри ViewController, они все еще технически являются его частью и могут быть переопределены, если вы захотите использовать реализацию, отличную от реализации по умолчанию. Экземпляр также позволяет вам настраивать такие вещи, как MaximumValidAge без изменения кода.

...