Iterator
The Videos
The Code
https://github.com/diegopacheco/java-pocs/tree/master/pocs/simple-iterator
Cheers,
Diego Pacheco
The Videos
The Code
https://github.com/diegopacheco/java-pocs/tree/master/pocs/simple-iterator
Cheers,
Diego Pacheco
Dependency Management Best Practices
Often Best practices are depending on contexts. Once you have complexity several times, best practices do not necessarily translate from one company to another; however, there are cases where they apply and make sense, not always, but for Dependency management IMHO, these are Golden Rules and excellent practices to be followed. Here are some Dependency Management best practices:
Dependency management is not only about using some specific or better tools. It's about a process and culture which requires attention and automation as well. Let's do a deep dive into each of these practices and understand why they are important.
Use the Dependency management tool (ant, maven, gradle). Do Explicit Dependency management.
It might sound obvious but it's not uncommon to see infrastructure projects downloading binaries manually and not using explicit dependency management via tools like Ant/ivy, Maven, and Gradle. No Matter the language you use, no matter if is an engineering or DevOps code, you should do explicit dependency management. Because is easier to maintain and we can relly on common process and tools for improvements and housekeeping.
Explicit dependency management means, explicit defining dependencies on a file that is used by the dependency management tool. You should avoid having embedded dependency and scripts who download dependencies outside of your main tool.
Use Artifact Management Solution (Nexus, Archiva, Artifactory) - Management but Mainly: Cache
Software tends to grow with your business. As you grew build times can get very slow. A cache is a must-have feature. Because there are multiple engineers downloading artifacts from the web and you often have multiple cloud environments like DEV, STAGING, STREE, PROD, etc... Dependency management solutions like Nexus, Archiva, Artifactory, also can help with better dependency management but one of the main benefits is to have a central cache and central repository management/location.
Remove dependencies you dont use.
This might sound silly. But un-used dependencies are bad as Dead Code because they make upgrade efforts harder and they end up creating technical debt. It's not uncommon that dependencies have 3rd party dependencies too and you might be dependency from a 3rd party dep instead from a direct dep and have that scenario for a dep you dont use is bad. It's unclear, confusing, raise false positives, and makes reasoning about refactoring efforts much much harder.
Use Consistency Versioning (MAJOR, MINOR, SEC/PATCH).
Versioning is something old as the snakes in the jungle(like we use to say in Brazil). However people still dont get it right. Why? People know when to use MAJOR(Major API Breaking change), Minor(Minor change no breaking backward compatibility), and Security/Patch release (minor bug fixe or security patch, not impact). But people do not do it. Why? Most of the time is a combination of lack of discipline and lack of ownership and pain of upgrading people dependencies. Central teams can be great in sense of reducing some costs but certainly, they hide some of the pains that if people would face them directly the would definitely deal with the problem differently. Having consistent versioning is super important, for Design, for Testing, and for health engineering practice I would argue. This part requires discipline and every single binary should embrace this principle.
Do not use multi-project EXTERNAL POMS.
Don't be fooled by the word POM. This principle works for any dependency management tool. You should not share multi-project external configs for dependency management. Either you have a monolith or monorepo where you have all code in one place or if you do have multiple github repositories you should not share these files(poms). Because? Well because they are EVIL. They create coupling they make upgrades harder and they kill microservices.
If you will have shared libraries they should be:
* Small
* Independent
* Isolated (dont have poms, not share configs)
Otherwise, you will build a distributed monolith and binary coupling will prevent you from upgrade when you need it. Never trade coupling for convenience or developer experience. However, if you have a monolith or a monorepo is perfectly fine to share poms.
Keep Dependencies up to Date (But does not update at deploy time - Immutable Infrastructure)
Another super important practice is to keep your dependencies updates. Thats important for several reasons such as:
* Prevent Bugs
* Fix Security Bugs
* Reduce Tech Debt
Update Dependencies often works with the same principles as Branches in Configuration Management. If you gonna have a long-lived branch(which you should avoid at all costs) you need to do merges every day so it reduces the complexity and issues on an old fashion bing bang boom merge. Libraries updates work in the same way. For minor, security patches, even minors should be able to upgrade it easily.
DevOps has a principle called - Immutable Infrastructure, you do not want to upgrade libs before doing a deploys or when a service restart. Because that breaks the principle of immutable infrastructure. However, at the same time, you want to AUTOMATE your dependency management and update libs frequently. Often engineers do not have the mindset to keep updating libs, which can be fixed with proper plugins and automation.
Use Dependencies Carefully (Shared-Libs) avoid coupling as much as you can.
When we ship internal shared libraries we need to be very careful. Shared Libs should be treated by applying the same principles we apply for Services. It's super important to pay extra attention to 3rd party deps in shared libs in order to avoid binary coupling. It's fine to use shared-libs, sometimes thats the right solution, however, there is a huge abuse of internal shared libs on the technology industry.
Better Dependency management helps Design and Testing. It makes CI/CD more effective and in the long-run increases the speed and ability to ship better and more frequent software. Currently, we live in an era where every company is trying to do proper CI/CD, Observability, Services, DevOps, SRE, and many other important matters however we often forget dependency management is an important sub-part of Building that end ups charging a high price at scale.
Cheers,
Diego Pacheco

The Video
The Code
https://github.com/diegopacheco/java-pocs/tree/master/pocs/java-15-fun
Cheers,
Diego Pacheco

BFFs the Benefits
Let's say you have a big app or multiple apps with multiple platforms like IoS and Android. Let's say you also have multiple sites or web application, it will be common to have a design system where you company want to have a standard view of the brand experience(colors, fonts, tons, etc...). It's important to leverage components, if you are working with React thats even easier and natural. However, another dilemma that often happens is, should I make a design system component, or thats something just for the app? Well, that is a couple of factors that could help you to figure it out.
* How many apps/sites will have that feature/component?
* How often that behavior it's likely to change?
* How complex is to make the component?
Even if you decide to go one route vs another route you can always refactor. So refactorings are cheap others are not, so as you grow you need to keep asking these questions. But regardless of what kind of component you end up doing or not doing you have benefits on the BFFs like:
* Caching
* Sever Side Rendering - Which also can be done in a generic way.
* Centralize and Re-use UI Logic (not business logic)
However, sometimes the UI Logic can easily be seen as business logic, in some sense microservices are making this much worst them it is.
Microservices are making BFFs Fat
I remember first waves of SOA where the default was to write code on the service, the services end up being FAT and with stuff that supposes not to be there. However, I also remember we having Aggregation Services, which were services that call other services and that was like the Gateway Uber is talking about on the re-discover of DDD post on DOMA.
Right now we have a different default, meaning, do not put stuff on the service, they need to be micro. The consequence is that complexity is pulled upwards. Complexity needs to live somewhere and microservices right now tend to be super simple and small however all the orchestration/choreography is being done by the BFFs which are getting more fat and complex.
It's a Governance Problem
IMHO we need Services, not Microservices. Services should be a bit more FAT. It's fine if the BFF is also FAT as long as it makes sense. So we are talking about a governance problem, that we need to answer some of the following questions:
* Where we put our code? (BFF, Aggregator Service / Gateway, Service)?
* Are the decisions we made on the past still make sense?
* Are we running joint Event-Storming exercises to figure out boundaries?
* How do we version APIs? Do we provide forward and backward compatibility? for how long?
* How we expose APIs? HTTP/2, gRPC?
*How own what component?
*How we test things properly? Are we having WASTE on our tests?
*How we coordinate cross-team efforts?
*Do we create a lib instead? Sidecar?
It's also a management problem
There are lots of options to manage this kind of cross-coordination. Do we have a big team as just have a big kanban to handle it? Do we have a chapters/guild(Spotify) to take care of that? Do we have a small pizza team(amazon) to execute the changes? Amazon's way relies on autonomy as a business construct and lean way it kind of makes a lot of sense because of the dependencies and lack of business autonomy you might end up here. When I say business autonomy I dont mean if you company has a cool culture and people are allowed to experiment and do stuff. I mean autonomy is a business construct, so you need to be able to generate results by ourself otherwise you always will have dependencies and you might be better served by the lean model.
Guidelines and Reflection Over Rules
Rules should be avoided because like any Design and Architecture matter we need to apply judgment. There is no one size fits all, so thats why rules are complicated. Judgment might be right or wrong or it might be right for a period of time and them things change and it's not valid anymore. For all those reasons we need continuous reflection, via big long retrospectives and working groups. Dilemmas are not bad, they are good actually it forces us to think which is our job. If we are not thinking a lot we might be following things we dont understand and creating debt and problems for the future :-)
Guidelines are awesome because they are not hard rules, you should have very few hard rules in a sense of design and architecture. Guidelines are educative and teach people how to approach problems. One thing I use a lot with Guidelines is Principles, I love principles they are great and I few the industry needs to use them more.
Cheers,
Diego Pacheco














