Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Being SOLID

Being SOLID

MVVM, VIPER, MVC are quite different approaches to architecturing mobile applications. But they are based on several fundamental principles, like SOLID. Whatever architectural pattern you choose to use following these simple principles will help you write clean and maintainable code.

It's best to learn from mistakes. We are going to talk about each SOLID principle in the following way: "Violation of principle -> Discussion -> Refactoring". After this talk the audience should clearly understand how to apply SOLID principles to typical iOS development problems.

Sergey Krapivenskiy

November 17, 2016
Tweet

More Decks by Sergey Krapivenskiy

Other Decks in Programming

Transcript

  1. Fundamentals • Data structures • Algorithms • Design patterns •

    DRY, KISS, YAGNI • SOLID • And a lot more
  2. AppDelegate App launch Quick actions Spotlight Push notifications Open from

    URL App states Background tasks Handoff Extensions https://github.com/rambler-digital-solutions/RamblerAppDelegateProxy
  3. } 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];
  4. } 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];
  5. } 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];
  6. } 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];
  7. } 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];
  8. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { id model =

    [self modelAtIndex:indexPath.row]; UITableViewCell<ConfigurableCell> *cell = ...; [cell configureWithObject:model]; return cell; }
  9. - (void)hideViews { [UIView animateWithDuration:1.0 animations:^ { for (UIView *view

    in self.animatableViews) { view.alpha = 0.5f; } }]; }
  10. UIView UIVisualEffectView Looks fine ! <UIVisualEffectView> is being asked to

    animate its opacity. This will cause the effect to appear broken until opacity returns to 1
  11. UIView UIVisualEffectView Looks fine ! <UIVisualEffectView> is being asked to

    animate its opacity. This will cause the effect to appear broken until opacity returns to 1
  12. UIView UIVisualEffectView Looks fine ! <UIVisualEffectView> is being asked to

    animate its opacity. This will cause the effect to appear broken until opacity returns to 1
  13. 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
  14. AuthService MailboxService ContactService MessageService 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
  15. - sendSelfDestructMessage - deleteBothMessages ChatChannel - loadMessages - sendMessage -

    replyToMessage - forwardMessage Channel SecretChat Supergroup - banUser Group - pinMessage
  16. - 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
  17. Dependency Inversion Principle “A. High-level modules should not depend on

    low-level modules. Both should depend on abstractions”
  18. - (void)displayNews { NSPredicate *newsPredicate = ...; NSArray *news =

    [News MR_findAllWithPredicate:newsPredicate]; // Show news } Depending on Core Data
  19. @protocol NewsProvider <NSObject> - (NSArray *)obtainNewsForDate:(NSDate *)date; @end Depending on

    abstraction - (void)displayNews { NSDate *todayDate = ...; NSArray *news = [self.newsProvider obtainNewsForDate:todayDate]; // Show news }
  20. @protocol NewsProvider <NSObject> - (NSArray *)obtainNewsForDate:(NSDate *)date; @end Depending on

    abstraction - (void)displayNews { NSDate *todayDate = ...; NSArray *news = [self.newsProvider obtainNewsForDate:todayDate]; // Show news }