-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extract helpers.ts #764
Extract helpers.ts #764
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it makes any sense to make one class to encapsulate private functions. You could accomplish the exact same thing by not exporting the private functions from the module. There's no benefit to OOP because instances of the websoc query class don't inherently manage any individual data, this is a perfect scenario to apply procedural programming because all you're doing is processing data in -> data out with not many side effects. (There aren't even multiple instances, it's just one). Am I missing something? |
The websoc class also has its cache, which makes sense as a private field and changes as a side effect when the public methods are called. I don't really see the downside of this approach vs a module with functions we don't export |
If that's the only benefit of having this class, then I think it would be clearer if everything was static. For example: export class Websoc {
private static cache = {}
public static async query() {
// ...
}
}
// Usage:
Websoc.query(...) In my opinion, I just dislike this illusion of encapsulation. The constructor doesn't actually do anything unique per instantiation, and the class itself isn't used in a way that actually takes advantage of OOP; it's literally just a couple of methods that are invoked like regular functions, but now you need to say I think static would be a valid compromise because it's "closer" to the level of module instantiation in that it doesn't readily support unique behavior per instance, and can exist just to encapsulate variables and mutate them freely (since imports/exports are immutable by the ES6 standard). Also, we should migrate to Tanstack query eventually ™️, which handles rendering and caching. So the most ideal scenario in the future is that these are just procedural functions that fetch data for the library's hooks, and the library handles caching, mutations, and other server-side state altogether. (i.e. the endgoal is to not have a class). |
This is equivalent to using a static class. The interface would be the same. Again, I'm not married to OOP; there's no reason a singleton is better than static here. It should be a class because it has state and side effects. Every function accesses it. It's not really a valid point to say, "well it doesn't have that much state", because having state just sitting around in the module is unclear in the opposite direction. It's not just data in -> data out, so that shouldn't be indicated. Also, I strongly prefer This is not about encapsulation or safety in some way. It's cleaner and clearer. I'm not familiar with Tanstack. What's the advantage there? |
Summary
Extract all course/WebSOC-related functionality to the
WebSOC
class in$lib/websoc.ts
. There should be no change in behaviorI do not sleep with OOP, but my God is this better than the garbage can that was the old
helpers.ts
.Test Plan
Check that everything works. I can't get too much more specific than that.
This PR mostly touches on WebSOC data request, caching, and manipulation functionality, so checking if things load properly is the priority.
Issues
Closes #760