Was ist Switch und wie geht man damit um?

Ein Programm ohne Verzweigung ist ein sehr einfaches und seltsames Programm. Das Programm sollte denken, Optionen berechnen, auf verschiedene äußere Einflüsse unterschiedlich reagieren und überhaupt nicht einheitlich sein. Und das alles ist ohne Verzweigung nicht möglich. Verzweigungen werden mit den Operatoren if und switch implementiert. Also warum solltest du gegen ihn kämpfen?

Wenn ich den Code eines anderen betrachte, stoße ich in regelmäßigen Abständen auf lange Methoden und umständliche Konstruktionen von verschachtelten if- und switch-Befehlen. Zum Beispiel:

// Примеры кода приведены на 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;
        }
    }
}


Persönlich erschrecken mich solche Methoden und sie passen einfach nicht in meinen Kopf. Das erste, wonach Sie fragen, ist, allen magischen Zahlen Namen zu geben. Zum Beispiel so:

enum SectionIndex {
    LoginSection = 0,
    DetailsSection,
    ExtendedSection
}


Bei genauerem Hinsehen berücksichtigen wir jedoch nicht den LoginSection, wenn der Wert self.loggedIn festgelegt ist, und verbergen den DetailsSection, wenn der Wert self.settings.showDetails zurückgesetzt wird. Wir konvertieren jedoch nur den Abschnittswert in SectionIndex basierend auf dem aktuellen Status:

- (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]
        }
    }
}


Meiner Meinung nach sieht es schon viel schöner aus, vor allem wenn man bedenkt, dass ein Objekt in der Regel mehrere Zweige enthält. Beispiel: -titleForItem: inSection :, -performActionForItem: inSection: usw. Was aber, wenn wir uns daran erinnern, dass unsere Sprache objektorientiert ist und der Zustand des Systems in einen Objektzustand versetzt werden kann? Dann werden alle diese Methoden auf eine Zeile reduziert - Zugriff auf das Statusobjekt?

- (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];
}


Meiner Meinung nach ist es ziemlich schön. Es bleibt nur, um diesen Zustand von irgendwoher zu bekommen. Sie können Statusobjekte im Objekt selbst konfigurieren oder mehrere Klassen schreiben, die Status definieren.


@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 {...}
// ...


Es hat sich herausgestellt, dass wir die Verzweigung an mehreren Stellen aufgegeben haben und sie durch eine Zustandseinstellung ersetzt haben, und die Zustände selbst haben sich als ganzheitlich, verständlich und an einem Ort zusammengefasst herausgestellt.

Jetzt auch beliebt: