I’m designing a backend in TypeScript (could also apply to JavaScript), and I’m wondering about the architectural approach.
Is it better to stick to a single paradigm (e.g., fully object-oriented or fully modular/functional), or is it acceptable — and maybe even recommended — to mix both styles?
For example:
Use an OOP approach (classes, methods, patterns like DAO, Repository, Service) for the business logic layer.
Use a modular approach (functions and exports) for routes and middleware in Express.
So, in practice:
Controllers and repositories → OOP
Routes and middleware → functional modules
Would such a hybrid architecture be considered good design practice, or should a backend project remain consistent with a single paradigm?
-
2Using functions/modules where most appropriate and classes where most appropriate is absolutely a good design practice.JacquesB– JacquesB2025年10月16日 15:36:05 +00:00Commented Oct 16 at 15:36
-
@JacquesB: I agree to this, though I guess in several (if not most) real world cases there is no good metrics what's most appropriate.Doc Brown– Doc Brown2025年10月16日 21:48:40 +00:00Commented Oct 16 at 21:48
-
I am using VueJS + DDD. OOP for the domain and the infra, and functions for the app (where most JS specific stuff lives) has been a nice experience.Bernardo Benini Fantin– Bernardo Benini Fantin2025年10月17日 20:10:56 +00:00Commented Oct 17 at 20:10
1 Answer 1
Most contemporary programming languages allow to use different paradigms like OOP or functional programming. This alone is neither good nor bad per se. However, when those different styles are mixed completely arbitrarily in a single layer, that can be a design smell.
A program keeps usually more comprehensible when it uses one (and only one) style for a certain layer. Your question already makes a reasonable suggestion in which area you want to use what, so I don't see a big risk of making your system overcomplicated by mixing styles. Another well known design principle which uses two paradigms in conjunction (but in different layers) is known as functional core - imperative shell.
Said that, there is usually nothing wrong when certain member functions of a class are utilizing functional tools, or when a mostly modular layer makes uses of certain classes or implements a helper class. So this isn't necessarily a black-and-white decision.
In the end, what matters most is how your team thinks about it. When they (during your code reviews) think the specific mixture is acceptable, then go ahead, Otherwise, better rethink and maybe refactor the system.
-
There is no such thing as a multi-paradigm. Paradigm is an absence/exclusion of options/behaviors. If two paradigms are used at the same time, both are corrupted (because their limitations/contracts are no longer observed) and at best become a third paradigm. I have yet to see a language that combines paradigms with logical AND.Basilevs– Basilevs2025年10月17日 12:55:39 +00:00Commented Oct 17 at 12:55
-
2@Basilevs that's fairly reductive. Multi-paradigm is a better description of the current state of a number of mainstream languages than any individual paradigmCaleth– Caleth2025年10月17日 14:08:47 +00:00Commented Oct 17 at 14:08
-
@Caleth that's indicative of a trend to eliminate paradigm as a concept. Consider on the other hand Rust - it has a strong paradigm of ownership. Or Haskell - purely functional (immutable) paradigm.Basilevs– Basilevs2025年10月17日 15:42:08 +00:00Commented Oct 17 at 15:42
-
@Basilevs: thank you for showing me that my answer had some potential to be misinterpreted. I hope my edit fixes this.Doc Brown– Doc Brown2025年10月17日 19:03:01 +00:00Commented Oct 17 at 19:03
-
It is fine either way, I just don't like the paradigm erosion that seems to happen these days.Basilevs– Basilevs2025年10月17日 19:31:00 +00:00Commented Oct 17 at 19:31
Explore related questions
See similar questions with these tags.