Slide 1

Slide 1 text

Кто подставил Барбару Лисков? Сергей Крапивенский, Rambler&Co или Кто кого SOLID?

Slide 2

Slide 2 text

“Do Not Learn Frameworks”

Slide 3

Slide 3 text

Фундаментальные знания

Slide 4

Slide 4 text

Фундаментальные знания Язык

Slide 5

Slide 5 text

Фундаментальные знания Язык Фреймворки

Slide 6

Slide 6 text

Фундаментальные знания Язык Фреймворки

Slide 7

Slide 7 text

RayWenderlich - driven development Senior ReactiveCocoa Developer Рамблер - секта VIPER

Slide 8

Slide 8 text

Фундаментальные знания Язык Фреймворки

Slide 9

Slide 9 text

Фундаментальные знания Язык Фреймворки

Slide 10

Slide 10 text

Фундаментальные знания Язык Фреймворки

Slide 11

Slide 11 text

Фундаментальные знания • Структуры данных • Алгоритмы • Паттерны • DRY, KISS, YAGNI • SOLID • И многое другое

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Single responsibility principle Open-closed principle Liskov substitution principle Interface segregation principle Dependency inversion principle

Slide 14

Slide 14 text

Single Responsibility Principle “A class should have only one reason to change”

Slide 15

Slide 15 text

MassiveViewController 1.Ответственности сильно связаны 2.Класс перестает помещаться в голове 3.Тяжело поддерживать и тестировать

Slide 16

Slide 16 text

UITableViewController 1.Изменение логики работы с таблицей 2.Поменять иерархию вьюшек

Slide 17

Slide 17 text

UITableViewController Решение проблемы: не использовать его

Slide 18

Slide 18 text

Запуск приложения Push Notifications Quick Actions Уведомления о состояниях приложения Открытие по URL Фоновая загрузка данных AppDelegate

Slide 19

Slide 19 text

AppDelegate Запуск приложения Quick Actions Поиск Push Notifications Открытие URL Состояния приложения Загрузка в фоне Handoff Extensions

Slide 20

Slide 20 text

AppDelegate Запуск приложения Quick Actions Поиск Push Notifications Открытие URL Состояния приложения Загрузка в фоне Handoff Extensions https://github.com/rambler-digital-solutions/RamblerAppDelegateProxy

Slide 21

Slide 21 text

SRP о снижении сложности

Slide 22

Slide 22 text

Single responsibility principle Open-closed principle Liskov substitution principle Interface segregation principle Dependency inversion principle

Slide 23

Slide 23 text

Open-Closed Principle “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”

Slide 24

Slide 24 text

Простой и устойчивый дизайн

Slide 25

Slide 25 text

Новость Новость Новость Новость

Slide 26

Slide 26 text

Новость Новость Новость Новость Новость с фото Новость с фото

Slide 27

Slide 27 text

Новость Новость Новость Новость Новость с фото Новость с фото Реклама Реклама

Slide 28

Slide 28 text

} else ... return cell } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SomeIdentifier")! as UITableViewCell let model = self.models[indexPath.row] if (model is News) { let newsCell: NewsCell? = (cell as? NewsCell) newsCell?.setup(withNews: model as! News) } else if (model is Advertisement) { let adCell: AdvertisementCell? = (cell as? AdvertisementCell) adCell?.setup(withAd: model as! Advertisement)

Slide 29

Slide 29 text

} else ... return cell } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SomeIdentifier")! as UITableViewCell let model = self.models[indexPath.row] if (model is News) { let newsCell: NewsCell? = (cell as? NewsCell) newsCell?.setup(withNews: model as! News) } else if (model is Advertisement) { let adCell: AdvertisementCell? = (cell as? AdvertisementCell) adCell?.setup(withAd: model as! Advertisement)

Slide 30

Slide 30 text

} else ... return cell } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SomeIdentifier")! as UITableViewCell let model = self.models[indexPath.row] if (model is News) { let newsCell: NewsCell? = (cell as? NewsCell) newsCell?.setup(withNews: model as! News) } else if (model is Advertisement) { let adCell: AdvertisementCell? = (cell as? AdvertisementCell) adCell?.setup(withAd: model as! Advertisement)

Slide 31

Slide 31 text

} else ... return cell } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SomeIdentifier")! as UITableViewCell let model = self.models[indexPath.row] if (model is News) { let newsCell: NewsCell? = (cell as? NewsCell) newsCell?.setup(withNews: model as! News) } else if (model is Advertisement) { let adCell: AdvertisementCell? = (cell as? AdvertisementCell) adCell?.setup(withAd: model as! Advertisement)

Slide 32

Slide 32 text

} else ... return cell } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SomeIdentifier")! as UITableViewCell let model = self.models[indexPath.row] if (model is News) { let newsCell: NewsCell? = (cell as? NewsCell) newsCell?.setup(withNews: model as! News) } else if (model is Advertisement) { let adCell: AdvertisementCell? = (cell as? AdvertisementCell) adCell?.setup(withAd: model as! Advertisement)

Slide 33

Slide 33 text

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let model: CellObject = self.models[indexPath.row] as! CellObject let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier")! as! ConfigurableCell cell.configure(withObject: model) return cell as! UITableViewCell }

Slide 34

Slide 34 text

NewsCell PhotoCell AdCell func configure(withObject: CellObject) News Photo Advert func cellClass() -> AnyClass

Slide 35

Slide 35 text

Когда применять?

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Single responsibility principle Open-closed principle Liskov substitution principle Interface segregation principle Dependency inversion principle

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

Liskov Substitution Principle “Subtypes must be substitutable for their base types”

Slide 40

Slide 40 text

Нужен для проверки корректности наследования

Slide 41

Slide 41 text

func hideViews() { UIView.animate(withDuration: 1.0, animations: { for view in self.animatableViews { view.alpha = 0.5 } }) }

Slide 42

Slide 42 text

UIView UIVisualEffectView Всё ок ! is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1

Slide 43

Slide 43 text

¯\_(ツ)_/¯

Slide 44

Slide 44 text

Single responsibility principle Open-closed principle Liskov substitution principle Interface segregation principle Dependency inversion principle

Slide 45

Slide 45 text

Interface Segregation Principle “Clients should not be forced to depend on methods that they do not use”

Slide 46

Slide 46 text

MailAPIClient - auth - findContact - getMailboxes - createMailbox - sendMail Auth Contacts Mailboxes Messages - auth - findContact - getMailboxes - createMailbox - sendMail - auth - findContact - getMailboxes - createMailbox - sendMail - auth - findContact - getMailboxes - createMailbox - sendMail - auth - findContact - getMailboxes - createMailbox - sendMail

Slide 47

Slide 47 text

AuthService MailboxService ContactService MessageServic e Auth Contacts Mailboxes Messages - auth - findContact - getMailboxes - createMailbox - sendMail - auth - findContact - getMailboxes - createMailbox - sendMail - auth - findContact - getMailboxes - createMailbox - sendMail - auth - findContact - getMailboxes - createMailbox - sendMail MailAPIClient

Slide 48

Slide 48 text

ISP - это не SRP

Slide 49

Slide 49 text

- sendSelfDestructMessage - deleteBothMessages ChatChannel - loadMessages - sendMessage - replyToMessage - forwardMessage Channel SecretChat Supergroup - banUser Group - loadMessages - sendMessage - replyToMessage - forwardMessage - sendSelfDestruct - deleteBoth - pinMessage - banUser - pinMessage - loadMessages - sendMessage - replyToMessage - forwardMessage - sendSelfDestruct - deleteBoth - pinMessage - banUser - loadMessages - sendMessage - replyToMessage - forwardMessage - sendSelfDestruct - deleteBoth - pinMessage - banUser - loadMessages - sendMessage - replyToMessage - forwardMessage - sendSelfDestruct - deleteBoth - pinMessage - banUser

Slide 50

Slide 50 text

Single responsibility principle Open-closed principle Liskov substitution principle Interface segregation principle Dependency inversion principle

Slide 51

Slide 51 text

Dependency Inversion Principle “A. High-level modules should not depend on low-level modules. Both should depend on abstractions”

Slide 52

Slide 52 text

Dependency Inversion Principle “B. Abstractions should not depend on details. Details should depend on abstractions”

Slide 53

Slide 53 text

func displayNews() { let newsPredicate = NSPredicate(...) let filteredNews = News.findAll() as! [News] // Отображаем новости } Зависимость от Core Data

Slide 54

Slide 54 text

NewsViewController MagicalRecord Realm

Slide 55

Slide 55 text

protocol NewsProvider { func obtainNewsForDate(date: NSDate) -> [News] } Зависимость от Core Data func displayNews() { let date = NSDate.init() let filteredNews = self.newsProvider?.obtainNewsForDate(date: date) // Отображаем новости }

Slide 56

Slide 56 text

protocol NewsProvider { func obtainNewsForDate(date: NSDate) -> [News] } Зависимость от Core Data func displayNews() { let date = NSDate.init() let filteredNews = self.newsProvider?.obtainNewsForDate(date: date) // Отображаем новости }

Slide 57

Slide 57 text

class ViewController: UIViewController { init(newsProvider : NewsProvider) { self.newsProvider = newsProvider super.init(nibName: "ViewController", bundle: nil) } } Зависимость от Core Data

Slide 58

Slide 58 text

NewsViewController MagicalRecord NewsProvider

Slide 59

Slide 59 text

Зависимости инвертированы #

Slide 60

Slide 60 text

Серебряной пули нет

Slide 61

Slide 61 text

- Оноре де Бальзак “Обстоятельства переменчивы, принципы - никогда”

Slide 62

Slide 62 text

Спасибо! serkrapiv sergey.krapivenskiy rambler-ios