Used to do DevOps before they even called it that way: Linux. Python. Perl. Java. Docker. For fun and profit. CTO level generalist working for a mid-sized tech-centric company.
Dresden, Germany
Great read in general, thanks for that. :) While I agree with most of the things mentioned here, including "use APIs for goodness' sake", I'd add another point to this nevertheless: Be very cautious about introducing dependencies that need to be managed at compile-time or even runtime. Two examples I'd count as "worst practises" here:
Loads of "single responsibility" services modeled as RESTful microservices and spread all across your system. While from a strict design point of view this might be good (enforces API usage, has small modules with very specific responsibilities, can be separately built, maintained, deployed, ...), this might leave you with a "runtime dependency hell" of a large set of components linked to each other in a loose yet somewhat strict coupling, with one system falling over and tearing down the whole rest of your application. Not really desirable. On such a larger scale, these days I guess I would rather focus on building isolated components talking to each other using APIs (yes) but having as little communication as somewhat possible between these components required at all.
In Java (as in several other languages) modularization often manifests in shared code libraries (maven dependencies, *.dlls, that kind of stuff). This, too, is something I learnt to be potentially dangerous. Take maven artifacts: As soon as you "release" a variant of a piece of code used by more than one application (internally or externally), you'll all of a sudden have a whole load more work to be done by either continuously maintaining, say, a v0.x.x, a v1.x.x and a v2.x.x of your shared library or continuously keep modifying all applications using this library to always work with the latest feature set and API it provides.
Both approaches are pretty likely to slow down your development, too, and might leave you with very interesting experiences of tearing down parts of your system in ways you didn't even imagine before. From that point of view, though I'd always follow your route for any architecture inside a single application (like a java .jar artifact, a single app or a single service module), I'd always suggest being rather careful and pragmatic about doing so as soon as you're about to leave the context of one single application...
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Great read in general, thanks for that. :) While I agree with most of the things mentioned here, including "use APIs for goodness' sake", I'd add another point to this nevertheless: Be very cautious about introducing dependencies that need to be managed at compile-time or even runtime. Two examples I'd count as "worst practises" here:
Loads of "single responsibility" services modeled as RESTful microservices and spread all across your system. While from a strict design point of view this might be good (enforces API usage, has small modules with very specific responsibilities, can be separately built, maintained, deployed, ...), this might leave you with a "runtime dependency hell" of a large set of components linked to each other in a loose yet somewhat strict coupling, with one system falling over and tearing down the whole rest of your application. Not really desirable. On such a larger scale, these days I guess I would rather focus on building isolated components talking to each other using APIs (yes) but having as little communication as somewhat possible between these components required at all.
In Java (as in several other languages) modularization often manifests in shared code libraries (maven dependencies, *.dlls, that kind of stuff). This, too, is something I learnt to be potentially dangerous. Take maven artifacts: As soon as you "release" a variant of a piece of code used by more than one application (internally or externally), you'll all of a sudden have a whole load more work to be done by either continuously maintaining, say, a v0.x.x, a v1.x.x and a v2.x.x of your shared library or continuously keep modifying all applications using this library to always work with the latest feature set and API it provides.
Both approaches are pretty likely to slow down your development, too, and might leave you with very interesting experiences of tearing down parts of your system in ways you didn't even imagine before. From that point of view, though I'd always follow your route for any architecture inside a single application (like a java .jar artifact, a single app or a single service module), I'd always suggest being rather careful and pragmatic about doing so as soon as you're about to leave the context of one single application...