1

I have a pretty general question about the design of Angular web applications. I'm a big fan of writing services. Sometimes I write services that have only utility methods that don't require state at all (think mathematical functions and the like). I feel that even in that case writing injectable services for the utility functions makes sense, since in that case you could swap different varieties of the service easily if you want to change the behavior of your application without having to delete old code inside of your static class.

To give an example: let's say we have a service that computes distances between points. You could just create that service as a plain old class with static methods to do it. But there are numerous ways to compute the distances between points. One might use the simple Euclidean formula, the somewhat more complex Haversine formula etc.

Suppose you'd want to pick the way to do it dynamically so users can choose the desired accuracy/complexity tradeoff. That's going to be a lot of spaghetti if you use a simple static class. On the other hand, it becomes rather simple if you have injectable distance services with a common base class/interface. This is a huge advantage and having state or not is irrelevant.

But still, in the context of web development with Angular this advantage might be tiny for some scenarios, even though it is good design. I was wondering if there is a certain point at which stateless services become so simple that the increase in bundle size or the decrease in (client-side) performance really begins to warrant just turning the service into a simple static class.

New contributor
Joshua Schroijen is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • surely with all the code bundled and minimised there is no downside? – Ewan May 15 at 14:26
  • I only have super-basic knowledge of the bundling and minification process. I don't really know how to test this quickly. – Joshua Schroijen May 15 at 14:34
  • 2
    The "certain point" you refer to is based entirely on your own assessment of the pros and cons of each approach, within the context of your specific project. You appear to be knowledgeable enough to make this assessment yourself. – Robert Harvey May 15 at 14:39
  • And if this is a performance discussion, the only way to know for sure is to measure. – Robert Harvey May 15 at 14:40
  • I'm on the fence about answering this. I don't have much to say about bundling and minification but I can tell you of patterns and principles I use to keep making everything injectable from driving you crazy. All without forcing you to couple. – candied_orange May 15 at 14:43
1

Performance is not the issue here. The real issue comes in when resolving the dependencies for the code using the "static" class (btw, a class is a Function object in JavaScript or just an object literal that can still be passed around like any other value).

If the "static" class is being pulled in to the page asynchronously using something like require.js then you have a race condition between the browser downloading the source code for the static class, and the code using the static class. Depending on who wins, you might get a JavaScript error.

For instance if you attempt to call a method on the static class while that JavaScript file is still being downloaded then you will get an error, because that object/class has not been defined yet in the lifecycle of the web page and web application.

Sticking with services in Angular allows the framework to load dependencies however it sees fit to ensure your code executes only when all of its dependencies have been downloaded, initialized and resolved.

I'm sure you don't need to do this. You can simply import the static class as a JavaScript file as a regular <script> tag, so that symbol is defined before Angular even comes into the picture, but that will increase the initial payload the browser must download before the page becomes something a user can interact with — and with enough of these kinds of files performance could start becoming an issue.

  • Your second paragraph seems unlikely. Surely require.js (or the browser itself) would have anticipated this. – Robert Harvey May 15 at 14:52
  • @RobertHarvey: If you do not declare that static class as a dependency in the definition of the file then require.js will not try sucking it down before executing the code. – Greg Burghardt May 15 at 14:53
  • Wow, thanks, that is a great viewpoint! – Joshua Schroijen May 16 at 8:07

Your Answer

Joshua Schroijen is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.