The previous book in this article picks up where theThis is the hardest part of DDD modeling (it's actually pretty easy)", welcome to my public number of the same name.
/s/HZKMLF0_I10iczzp2mAR-w
Background
In mid-2013, our Java back-end team fully introduced the dotnet technology stack in order to land DDD. For the specific process and results, you can see my B-site channel "Java8 to .NET8, Team Upgrade Report - Second Bullet" /video/BV14YgYedE1f
In the past six months, I have refined and summarized my practical experience in landing DDD, and shared it in the form of public number articles and B station videos to establish links and exchanges with more netizens, and received a lot of affirmative feedback, and because of the perspectives provided by all of you, it has led to a deeper iteration of my own perceptions of DDD.
With the powerful ecosystem of dotnet and the excellent language design of csharp, we have been able to express the model and business in code in a very silky smooth way, and the whole experience and efficiency of software delivery has gained unprecedented progress. Our netcorepal-cloud-framework framework has also evolved and validated its usability in this process, and we firmly believe that we have found a set of more pragmatic software design knowledge and methodology.
Javaer is too hard.
Since our team is still practically a dual technology stack of Java and csharp, we had an idea, could we make our Java project delivery process so silky smooth? With this idea in mind, we started to look for components in the Java ecosystem that could help us build a csharp-like framework:
- Web frameworks: aspnetcore vs springboot
- ORM:EntityFrameworkCore vs JPA
- The intermediary model: MediatR vs ?
- Final consistency realization of events: CAP vs ?
We didn't find any suitable alternatives for the implementation of "Intermediary Pattern" and "Final Consistency of Events", but after analyzing, the "Intermediary Pattern" is not necessary. After analysis, the "mediator pattern" is not necessary, although the final implementation is not as elegant as csharp, but it does not affect the implementation of the modeling design, but the "event event consistency" component, we believe that it is essential, our modeling of the lowest level of the model is the "command-event" model, without the robustness of the event processing, we will not be able to achieve the same result. Without the robustness of event processing, it means that the robustness of the final system can not be guaranteed, and ultimately can not meet the business requirements for availability.
Final consistency of events
In our modeling model, it is in the command processing logic that events are emitted by the domain model, and events, if they are to be passed between microservices, we expect to achieve the following:
- If the command processing logic succeeds, i.e., the corresponding database transaction commits successfully, it ensures that the event must be able to be issued;
- If the command processing logic fails, i.e., the corresponding database transaction is rolled back, it is ensured that the event must not be issued;
At the requirement level, we do not require the system to ensure that the event is "determined to be sent only once", we know that the technical implementation of this requirement is much more difficult than the previous two requirements, and the business can do idempotent processing to solve the problem of retransmission.
The following diagram shows our csharp implementation of the "command-event" modeling, and the implementation of transactions:
In our version of csharp, we use the popular CAP component, /dotnetcore/CAP, which essentially implements the outbox pattern, often called the "Outbox Pattern", and with the help of this component, we can easily achieve the ultimate consistency for events.
The following image from the introductory page of the CAP component shows exactly how the Outbox mode works:
In principle, the outbox model is not a complex capability, and we believe that it has always been based on theecologically soundFor the merits of the Java ecosystem, there must be similar and popular components, unfortunately, we have come to the following conclusions after some research on the Internet and in Java circles that we can reach:
- Java ecosystem has an implementation of distributed transactions , for example : JEE, JBoss , etc., but at present basically no team is using it ;
- The Java ecosystem doesn't have off-the-shelf components like CAP available out-of-the-box;
The above conclusions are only indicative of our current perceptions and information sources, so if any of the big boys can give a pointer, it would be appreciated!
cap4j
Based on the previous conclusions, in order to realize the practice of DDD code experience in Java projects, we open source a cap4j project, expecting to port the capabilities of the CAP project to the Java ecosystem, the project address: /netcorepal/cap4j
The project currently implements a combination of JPA + RocketMQ , we plan to support more ORM and MQ middleware in the future , but also will support the protocol compatibility with CAP components , in order to achieve further integration of Java, dotnet heterogeneous architecture . You are also welcome to contribute code and ideas to the project.
ultimate
On the matter of technological ecology, it is fair to say that Java'secologically sound, but the ecology of all the other languages I don't think are bad either, and have very much to offer in their respective fields. I always see all kinds of unrealistic and biased comments in the comments section, and I feel all kinds of malice. Expect various languages of the technology stack practitioners, can be more friendly exchanges, we are all software engineers, to meet business needs, to achieve business value, is what we should be more concerned about.