SlideShare a Scribd company logo
Кто подставил
Барбару Лисков?
Сергей Крапивенский, Rambler&Co
или Кто кого SOLID?
“Do Not Learn Frameworks”
Фундаментальные знания
Фундаментальные знания
Язык
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
RayWenderlich - driven development
Senior ReactiveCocoa Developer
Рамблер - секта VIPER
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
• Структуры данных
• Алгоритмы
• Паттерны
• DRY, KISS, YAGNI
• SOLID
• И многое другое
Сергей Крапивенский
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Single Responsibility Principle
“A class should have only one
reason to change”
MassiveViewController
1.Ответственности сильно связаны
2.Класс перестает помещаться в голове
3.Тяжело поддерживать и тестировать
UITableViewController
1.Изменение логики работы с таблицей
2.Поменять иерархию вьюшек
UITableViewController
Решение проблемы: не использовать его
Запуск приложения
Push Notifications
Quick Actions
Уведомления о
состояниях приложения
Открытие по URL
Фоновая
загрузка данных
AppDelegate
AppDelegate
Запуск приложения Quick Actions
ПоискPush Notifications
Открытие URL
Состояния
приложения
Загрузка в фоне
Handoff
Extensions
AppDelegate
Запуск приложения Quick Actions
ПоискPush Notifications
Открытие URL
Состояния
приложения
Загрузка в фоне
Handoff
Extensions
https://github.com/rambler-digital-solutions/RamblerAppDelegateProxy
SRP о снижении сложности
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Open-Closed Principle
“Software entities (classes,
modules, functions, etc.) should be
open for extension, but closed for
modification”
Простой и устойчивый
дизайн
Новость
Новость
Новость
Новость
Новость
Новость
Новость
Новость
Новость с фото
Новость с фото
Новость
Новость
Новость
Новость
Новость с фото
Новость с фото
Реклама
Реклама
} 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)
} 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)
} 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)
} 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)
} 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)
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
}
NewsCell PhotoCell AdCell
<ConfigurableCell>
func configure(withObject: CellObject)
News Photo Advert
<CellObject>
func cellClass() -> AnyClass
Когда применять?
Сергей Крапивенский
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Сергей Крапивенский
Liskov Substitution Principle
“Subtypes must be substitutable for
their base types”
Нужен для проверки
корректности наследования
func hideViews() {
UIView.animate(withDuration: 1.0,
animations: {
for view in self.animatableViews {
view.alpha = 0.5
}
})
}
UIView
UIVisualEffectView
Всё ок !
<UIVisualEffectView> is being asked to animate its
opacity. This will cause the effect to appear broken until
opacity returns to 1
¯_(ツ)_/¯
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Interface Segregation Principle
“Clients should not be forced to
depend on methods that they
do not use”
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
AuthServiceMailboxServiceContactService
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
ISP - это не SRP
- sendSelfDestructMessage
- deleteBothMessages
ChatChannel
- loadMessages
- sendMessage
- replyToMessage
- forwardMessage
ChannelSecretChat 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
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Dependency Inversion Principle
“A. High-level modules should not
depend on low-level modules. Both
should depend on abstractions”
Dependency Inversion Principle
“B. Abstractions should not depend
on details. Details should depend
on abstractions”
func displayNews() {
let newsPredicate = NSPredicate(...)
let filteredNews = News.findAll() as! [News]
// Отображаем новости
}
Зависимость от Core Data
NewsViewController MagicalRecord
Realm😓
protocol NewsProvider {
func obtainNewsForDate(date: NSDate) -> [News]
}
Зависимость от Core Data
func displayNews() {
let date = NSDate.init()
let filteredNews = self.newsProvider?.obtainNewsForDate(date:
date)
// Отображаем новости
}
protocol NewsProvider {
func obtainNewsForDate(date: NSDate) -> [News]
}
Зависимость от Core Data
func displayNews() {
let date = NSDate.init()
let filteredNews = self.newsProvider?.obtainNewsForDate(date:
date)
// Отображаем новости
}
class ViewController: UIViewController {
init(newsProvider : NewsProvider) {
self.newsProvider = newsProvider
super.init(nibName: "ViewController", bundle: nil)
}
}
Зависимость от Core Data
NewsViewController <NewsProvider>
MagicalRecord
NewsProvider
Зависимости инвертированы #
Серебряной пули нет 😢
- Оноре де Бальзак
“Обстоятельства переменчивы,
принципы - никогда”
Спасибо!
serkrapiv
sergey.krapivenskiy
rambler-ios

More Related Content

PDF
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
PDF
50 оттенков play!
PDF
Spring Boot Ripper
PPTX
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
PDF
Превышаем скоростные лимиты с Angular 2
PDF
How to build solid CI-CD pipeline / Илья Беда (beda.software)
PDF
«Как перестать отлаживать асинхронные вызовы и начать жить»​
PPT
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
50 оттенков play!
Spring Boot Ripper
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
Превышаем скоростные лимиты с Angular 2
How to build solid CI-CD pipeline / Илья Беда (beda.software)
«Как перестать отлаживать асинхронные вызовы и начать жить»​
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...

What's hot (20)

PPTX
антон веснин Rails Application Servers
PPTX
Online TechTalk “Flutter Mobile Development”
PDF
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
PDF
Пользователь точно оценит! Повышение производительности мобильных приложений ...
PPTX
Service Discovery. More that it seems
PPTX
Konstantin slisenko - Spring Framework
PPTX
Микрофреймворки PHP
PPTX
Простой и кросс-платформенный WEB-сервер на .NET
PDF
Разработка Enterprise-приложения на основе Spring Framework
ODP
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
PDF
"Web Vitals monitoring & optimizations", Erik Himiranov
PPTX
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...
PDF
Бэкенд, фронтенд — всё смешалось (nodkz)
PDF
Java 9: what is there beyond modularization
PDF
Максим Пугачев
PPTX
RESTful API: Best practices, versioning, design documentation
PDF
Stability in unstability self healing test automation - selenium camp
PDF
"Посмотрим на Акку-Джаву" Дмитрий Мантула
PDF
Переход с Objective-C на Swift — все ли так просто? / Олег Алексеенко (SuperJob)
PPTX
2021.11.10 Dots Platform. Serverless. Vapor
антон веснин Rails Application Servers
Online TechTalk “Flutter Mobile Development”
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
Пользователь точно оценит! Повышение производительности мобильных приложений ...
Service Discovery. More that it seems
Konstantin slisenko - Spring Framework
Микрофреймворки PHP
Простой и кросс-платформенный WEB-сервер на .NET
Разработка Enterprise-приложения на основе Spring Framework
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
"Web Vitals monitoring & optimizations", Erik Himiranov
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...
Бэкенд, фронтенд — всё смешалось (nodkz)
Java 9: what is there beyond modularization
Максим Пугачев
RESTful API: Best practices, versioning, design documentation
Stability in unstability self healing test automation - selenium camp
"Посмотрим на Акку-Джаву" Дмитрий Мантула
Переход с Objective-C на Swift — все ли так просто? / Олег Алексеенко (SuperJob)
2021.11.10 Dots Platform. Serverless. Vapor
Ad

Similar to Сергей Крапивенский (20)

PDF
Being SOLID
PPTX
Yii2
PPTX
Референсная архитектура приложения на ASP.NET MVC
PPTX
ASP.NET MVC
PDF
JavaScript Базовый. Занятие 09.
PDF
C# Web. Занятие 11.
PDF
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
PPTX
Построение собственного JS SDK — зачем и как?
PPTX
AngularJS. Введение и простые примеры для понимания
PDF
Bloch, bodoff руководство. сервлеты
PDF
Антипаттерны модульного тестирования (Донецкий кофе-и-код Сентябрь 2010)
PDF
C# Web. Занятие 09.
PDF
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
PDF
Grails & Groovy
PPTX
ASP.NET, MVC, ASP.NET MVC
PDF
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
PDF
Контроль качества верстки или как начать делать Makeup
PDF
Александр Кашеверов - Коротко про WEB
PDF
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Being SOLID
Yii2
Референсная архитектура приложения на ASP.NET MVC
ASP.NET MVC
JavaScript Базовый. Занятие 09.
C# Web. Занятие 11.
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
Построение собственного JS SDK — зачем и как?
AngularJS. Введение и простые примеры для понимания
Bloch, bodoff руководство. сервлеты
Антипаттерны модульного тестирования (Донецкий кофе-и-код Сентябрь 2010)
C# Web. Занятие 09.
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
Grails & Groovy
ASP.NET, MVC, ASP.NET MVC
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Контроль качества верстки или как начать делать Makeup
Александр Кашеверов - Коротко про WEB
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Ad

More from CodeFest (20)

PDF
Alexander Graebe
PDF
Никита Прокопов
PPTX
Денис Баталов
PDF
Елена Гальцина
PDF
Александр Калашников
PDF
Ирина Иванова
PDF
Marko Berković
PDF
Денис Кортунов
PDF
Александр Зимин
PDF
Сергей Игнатов
PDF
Николай Крапивный
PDF
Alexander Graebe
PDF
Вадим Смирнов
PDF
Константин Осипов
PDF
Raffaele Rialdi
PDF
Rene Groeschke
PDF
Иван Бондаренко
PDF
Mete Atamel
PDF
Алексей Акулович
PDF
Артем Титаренко
Alexander Graebe
Никита Прокопов
Денис Баталов
Елена Гальцина
Александр Калашников
Ирина Иванова
Marko Berković
Денис Кортунов
Александр Зимин
Сергей Игнатов
Николай Крапивный
Alexander Graebe
Вадим Смирнов
Константин Осипов
Raffaele Rialdi
Rene Groeschke
Иван Бондаренко
Mete Atamel
Алексей Акулович
Артем Титаренко

Сергей Крапивенский