Skip to content

Instantly share code, notes, and snippets.

@mt3o
Created June 18, 2024 16:34
Show Gist options
  • Save mt3o/5c18522701c4c0730e9f5517ae429b08 to your computer and use it in GitHub Desktop.
Save mt3o/5c18522701c4c0730e9f5517ae429b08 to your computer and use it in GitHub Desktop.
TS Polyomrphic patterns
// Very bad
const config={
where: "disk"|"redis"
}
if(config.where=="disk"){
//explicit code to save to disk
}else if(config.where=="redis"){
//explicit code to handle redis
}
// it's very bad because the actual code is scattered all around the application
// and its difficult to spot all places refering to that code. No separations of concerns
//-------------------
// Bad
class DataWriter{
construct(where:"disk"|"redis"){}
write(data){
if(this.where=="disk"){
//explicit code to save to disk
}else if(this.where=="redis"){
//explicit code to save to redis
}
}
}
// It's bad because we have 1 god-like class.
// It's better than first one, because the class encapsulates all the writing logic
// ------------------
// Good
interface DataWriter{
save(data:Buffer):Promise<void>
}
class DiskWriter implements DataWriter{
save(data){/*save to disk*/}
}
class RedisWriter implements DataWriter{
save(data){/*save to redis*/}
}
// It's good because separate classes handle specific implementations.
// For rest of the project - the data writing mechanics are abstracted away, and hidden.
// Particular implementation, Disk or Redis, can be injected by DI container depending on the config.
// Rest of the code receives just the DataWriter object, and doesn't know which implementation is in use.
/* Further reading:
- https://refactoring.guru/pl/replace-conditional-with-polymorphism
- https://theobjectorientedway.com/chapters/replace-conditional-with-polymorphism.html
- https://lean-lang.org/functional_programming_in_lean/getting-to-know/polymorphism.html
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment