Skip to content

Instantly share code, notes, and snippets.

@grigory-rechistov-intel
Last active October 4, 2024 13:11
Show Gist options
  • Save grigory-rechistov-intel/5a7a71e1106d3621b11463285c507cd5 to your computer and use it in GitHub Desktop.
Save grigory-rechistov-intel/5a7a71e1106d3621b11463285c507cd5 to your computer and use it in GitHub Desktop.
Replace switch-case's with polymorphism
// === 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