📜 ⬆️ ⬇️

What is a switch and how to deal with it?

A program without branching is a very simple and strange program. The program should think, figure out the options, respond differently to various external influences and not be monotonous at all. And this is all impossible without branching. Branches are implemented using the if and switch statements. So why bother with him?

Periodically, when viewing someone else's code, I come across long methods and cumbersome constructions of nested if and switch. For example, such:

//     Objective C,           - (NSUInteger)numberOfItemsInSection:(NSUInteger)section { if (self.loggedIn) { swtich (section) { case 0: return 2; case 1: { if (self.settings.showDetails) { return 5; } else { return 3; } } case 2: return 3; } } else { swtich (section) { case 1: { if (self.settings.showDetails) { return 5; } else { return 3; } } case 2: return 3; } } } 


Me personally, such methods are scary and they just do not fit in my head. The first thing that is asked is to give names to all magic numbers. For example:
')
 enum SectionIndex { LoginSection = 0, DetailsSection, ExtendedSection } 


But if you take a closer look, we do not consider LoginSection if the value is set to self.loggedIn and hide DetailsSection if the value of self.settings.showDetails is reset. But we simply convert the value of section to SectionIndex based on the current state:

 - (SectionIndex)sectionIndexForSection:(NSUInteger)section { if (!self.loggedIn) { ++section; } if (!self.settings.showDetails) { ++section; } return (SectionIndex)section; } - (NSUInteger)numberOfItemsInSection:(NSUInteger)section { SectionIndex sectionIndex = [self sectionIndexForSection:section]; switch (sectionIndex) { case LoginSection: return [self numberOfItemsInLoggedInSection]; case DetailsSection: return [self numberOfItemsInDetailsSection]; case ExtendedSection: return [self numberOfItemsInExtendedSection] } } } 


In my opinion, it already looks much nicer, especially considering that there are usually several such branches in an object. For example, -titleForItem: inSection :, -performActionForItem: inSection:, etc. But what if we recall that our language is object-oriented, and the state of the system can be brought into an object-state? Then all these methods will be reduced to one line - referring to the state object?

 - (NSUInteger)numberOfSections { retun [self.state numberOfSections]; } - (NSUInteger)numberOfItemsInSection:(NSUInteger)section { retun [self.state numberOfItemsInSection:section]; } - (NSString *)titleForItem:(NSUInteger)item inSection:(NSUInteger)section { retun [self.state titleForItem:item inSection:section]; } - (void)performActionForItem:(NSUInteger)item inSection:(NSUInteger)section { retun [self.state performActionForItem:item inSection:section]; } 


In my opinion, quite beautiful. It remains only to get somewhere from this very state. You can configure state objects in the object itself or write several classes that define states.

 @interface State : NSObject @property (nonatomic, strong) NSArray *sections; // ... @end @implementation State - (NSUInteger)numberOfSections { return [self.sections count]; } - (NSUInteger)numberOfItemsInSection:(NSUInteger)section { return [self.sections[section] count]; } - (NSString *)titleForItem:(NSUInteger)item inSection:(NSUInteger)section { return self.sections[section][item][@"title"]; } - (void)performActionForItem:(NSUInteger)item inSection:(NSUInteger)section { void(^actionBlock)() = self.sections[section][item][@"action"]; actionBlock(); } //   - (void)setupForState { NSMutableDictionary *state = [NSMutableDictionary dictionary]; if (self.loggedIn) { [state addObject:[self loggedInSection]]; } if (self.showDetails) { [state addObject:[self detailsSection]]; } [state addObject:[self extendedSection]]; self.sections = state; } - (NSArray *)loggedInSection {...} - (NSArray *)detailsSection {...} - (NSArray *)extendedSection {...} // ... 


It turns out that we got rid of branches in several places, replacing it with one setting of the state, and the states themselves turned out to be complete, understandable and collected in one place.

Source: https://habr.com/ru/post/218119/


All Articles