SlideShare a Scribd company logo
Кто подставил
Барбару Лисков?
или Кто кого SOLID?
Сергей Крапивенский, Rambler&Co
как сказал наш великий полководец Суворов
“Do Not Learn Frameworks”
Фундаментальные знания
Фундаментальные знания
Язык
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
RayWenderlich - driven development
Senior ReactiveCocoa Developer
Рамблер - секта VIPER
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
• Структуры данных
• Алгоритмы
• Паттерны
• DRY, KISS, YAGNI
• SOLID
• И многое другое
Being 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;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
Being SOLID
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
id model = [self modelAtIndex:indexPath.row];
UITableViewCell<ConfigurableCell> *cell = ...;
[cell configureWithObject:model];
return cell;
}
NewsCell PhotoCell AdCell
<ConfigurableCell>
- (void)configure:(<CellObject>)object;
News Photo Advert
<CellObject>
- (Class)cellClass;
Когда применять?
Being SOLID
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Being SOLID
Liskov Substitution Principle
“Subtypes must be substitutable
for their base types”
Нужен для проверки
корректности наследования
- (void)hideViews {
[UIView animateWithDuration:1.0
animations:^
{
for (UIView *view in self.animatableViews) {
view.alpha = 0.5f;
}
}];
}
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
AuthServiceMailboxServiceContactServiceMessageService
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”
- (void)displayNews {
NSPredicate *newsPredicate = ...;
NSArray *news = [News MR_findAllWithPredicate:newsPredicate];
// Отображаем новости
}
Зависимость от Core Data
NewsViewController MagicalRecord
Realm😓
@protocol NewsProvider <NSObject>
- (NSArray *)obtainNewsForDate:(NSDate *)date;
@end
Зависимость от Core Data
- (void)displayNews {
NSDate *todayDate = ...;
NSArray *news = [self.newsProvider obtainNewsForDate:todayDate];
// Отображаем новости
}
@protocol NewsProvider <NSObject>
- (NSArray *)obtainNewsForDate:(NSDate *)date;
@end
Зависимость от Core Data
- (void)displayNews {
NSDate *todayDate = ...;
NSArray *news = [self.newsProvider obtainNewsForDate:todayDate];
// Отображаем новости
}
@interface NewsViewController : UIViewController
- (instancetype)initWithNewsProvider:(id<NewsProvider>)newsProvider;
@end
Зависимость от Core Data
NewsViewController <NewsProvider>
MagicalRecord
NewsProvider
Зависимости инвертированы #
Серебряной пули нет 😢
- Оноре де Бальзак
“Обстоятельства переменчивы,
принципы - никогда”

More Related Content

PDF
Maksim Shirshin
PDF
Максим Ширшин "SVARX, или Борьба с большими формами"
PDF
Внутреннее устройство и оптимизация бандла webpack
PPT
Профилирование и оптимизация jQuery–кода
PPT
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
PDF
Сергей Крапивенский
PDF
Сергей Крапивенский
PPTX
Yii2
Maksim Shirshin
Максим Ширшин "SVARX, или Борьба с большими формами"
Внутреннее устройство и оптимизация бандла webpack
Профилирование и оптимизация jQuery–кода
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
Сергей Крапивенский
Сергей Крапивенский
Yii2

Similar to Being SOLID (20)

PDF
Grails & Groovy
PDF
Zend Framework и Doctrine
PDF
Пластилиновый код: как перестать кодить и начать жить
PPTX
automation is iOS development
PDF
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
PDF
Регрессионное тестирование верстки
PDF
C# Web. Занятие 11.
PDF
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
PPT
Take more from Jquery
PPTX
Построение собственного JS SDK — зачем и как?
ODP
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
PDF
JavaScript Базовый. Занятие 09.
PDF
Контроль качества верстки или как начать делать Makeup
PDF
UWDC 2013, Yii2
PPT
Easy authcache 2 кеширование для pro родионов игорь
PDF
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...
PDF
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
PDF
React со скоростью света: не совсем обычный серверный рендеринг
PDF
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
PPTX
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
Grails & Groovy
Zend Framework и Doctrine
Пластилиновый код: как перестать кодить и начать жить
automation is iOS development
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
Регрессионное тестирование верстки
C# Web. Занятие 11.
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Take more from Jquery
Построение собственного JS SDK — зачем и как?
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
JavaScript Базовый. Занятие 09.
Контроль качества верстки или как начать делать Makeup
UWDC 2013, Yii2
Easy authcache 2 кеширование для pro родионов игорь
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
React со скоростью света: не совсем обычный серверный рендеринг
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
Ad

Being SOLID