Last active
October 4, 2024 13:11
-
-
Save grigory-rechistov-intel/5a7a71e1106d3621b11463285c507cd5 to your computer and use it in GitHub Desktop.
Replace switch-case's with polymorphism
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// === Before === | |
typedef enum { | |
Access_Vanilla, | |
Access_Special, | |
Access_Cache, | |
Access_Cache_L2, | |
Access_Invalid | |
} access_t; | |
string get_name(access_t a) { | |
switch (a) { | |
case Access_Vanilla: | |
return "vanilla"; | |
case Access_Special: | |
return "special"; | |
case Access_Cache: | |
return "cache"; | |
case Access_Cache_L2: | |
return "cache L2"; | |
case Access_Invalid: | |
return "invalid"; | |
} | |
} | |
bool is_cached(access_t a) { | |
switch (a) { | |
case Access_Vanilla: | |
case Access_Invalid: | |
case Access_Special: | |
return false; | |
case Access_Cache: | |
case Access_Cache_L2: | |
return true; | |
} | |
} | |
void trigger_notification(access_t a, void *data) { | |
switch (a) { | |
case Access_Vanilla: | |
notify_vanilla(data); | |
break; | |
case Access_Cache: | |
case Access_Cache_L2: | |
notify_cache(data); | |
break; | |
default: | |
throw NotificationException(); | |
} | |
} | |
// ========================================================================= | |
// === After === | |
class Access { /* interface */ | |
public: | |
virtual string name() = 0; /* These are not functions, but rather pointers to functions! */ | |
virtual bool is_cached() = 0; | |
virtual notify(void *data) = 0; | |
}; | |
class VanillaAccess: public Access { | |
virtual string name() { | |
return "vanilla"; // note how `switch` has disappeared | |
} | |
... | |
}; | |
class SpecialAccess: public Access {...}; | |
... | |
class InvalidAccess: public Access {...}; | |
// the only remaining switch is hidden here | |
construct_access_by_tag(type) { | |
switch (type) { | |
case Access_Vanilla: | |
return VanillaAccess(); | |
case Access_Special: | |
return AccessSpecial(); | |
... | |
} | |
} | |
// Anywhere where we want to discriminate on access_t | |
access_t type = ...; | |
Access *access = construct_access_by_tag(type); | |
// The original functions after the refactoring | |
string get_name(Access *access) { | |
return access->name(); | |
} | |
bool is_cached(Access *a) { | |
return a->is_cached(); | |
} | |
void trigger_notification(Access *access, void *data) { | |
access->notify(data); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment