DDD: Thinking in terms of Context Map

In my previous article, I did a detailed discussion about the Bounded Context and learn that how to tackle the complexity of a Domain, it is the best way to divide the domains into several subdomains and mapped them with different bounded contexts where each business entity/Value object has certain meaning on that context, so every stakeholder of the business like Product owner, Developers, Architect, sponsorers are understood the context and referring entity with the proper name, there should be no confusion of the naming when we discuss the terminology basis on a context. A ubiquitous language which creates a unified language among business stakeholder.
By Bounded context, we properly define a business model, create a different context based on the business domains, but always a functionality spans over multiple business entities , and those entities lie in the different Bounded contexts/domains, so it is utmost important to understand the relationship between the Bounded contexts, to architecting the business solution Context Map is a technique by which we can visualize the relationship between different contexts and Integration architect choose the best integration patterns to communicate to other contexts.

Why Context Map is so important while designing solution?
By UML diagram architect cam understand how different parts will communicate with other parts, It gives the architect a view on the communication between different contexts, that is fine but context map stepped in before UML diagram, it helps to visualize the nature of the relationship and based on the nature , architects can decide what kind of technical solution would be adopted.
The best part of Context Map visualization is, it talks about nature of the relationship, It not only tell is that relationship is upstream or downstream, Publisher or subscriber, it also tells how different team dependent on another team their motifs, their politics everything. so counting all of that now architect in a position to decide optimal solution to minimize the risk while integrating with another context.
In the era of Microservices, Context Map is the key player, because before design the holistic Microservice architecture where every team owns a Microservice, It is important to understand how one team is dependent on other, which teams are in commendable position, which team only seeks help then you can architect the solution best possible way .
Think of our Student online Tutor app, as a full grown app say it has more than fifty microservices are deployed in production , so here fifty teams are coming into play and for developing a functionality say Student registrations , multiple contexts will be affected, so we can say to implement that feature multiple teams will be involved so what would be their relationship, while designing this feature who is the pivot service whose data is most needed obviously that service is in commendable position as if that team is not ready other teams can't do anything, so all teams should align with that team , they have to sync there product backlog with that team, so here the internal politics comes to the picture , if the data of the service comes from an External team not with in the organization then the solution is way more complex as you can't force them so only way is to request them and wait for there changes, so based on these diffrent scenarios, politics context map has diffrent solutions. I will cover most important solutions here
 1. Shared Kernel : Shared kernel talks about a partnership relation where two or many teams shared common data model/ value object, it reduces the code duplication as different context use that common model, but that common model/value object is very sensitive, any changes major/minor should be agreed upon all the parties unless it would break other parties code, so more communication and synchronization needs among those teams say one team need a change in the common model but another team is not ready so the priro team has to wait for other oartner to be ready or otherhand othar partner has to change there code unnecessery although that is not heliping them, but to be in sync with other partners, diffrent shades of problems woven while maintaining the pertnership relation ship so choose that pattern  when your common model remains constant or changes once in an era.
In our example, say we developed an analytical module which analysis which courses are most chosen by the students, which students are chosen more than five courses etc, so that module works with Student model, course model so I can say our Analytics module can share Registration modules student model, and they also agreed upon any changes on student model.

Customer/ Supplier: Generally this is the common relationship between two contexts, where a context consumers or depend on data from another context, the context which produces data marked as upstream and the context which consumes data called downstream. When we visualize this relationship in terms of politics we can visualize the power distribution has many shades.
like following
Upstream as the leader: In this type of relationship, the upstream team is in a commendable position, that team does not care about the downstream team, as they producing the data and downstream team is on the mercy of that upstream team they are always changing their model based on the data structure produces by upstream.
In our Student Registration app relationship between Payment app and Notification, app is kind of upstream and downstream where Payment app decide what information in which structure they provide and Notification module consumes that data structure.

Downstream as the Leader: In some cases, the relationship is revert although upstream is produces data, it must have to follow the rule, the data structure for downstream, in this scenario downstream is in a commendable position.
say in our Studen registration system we need to submit Form 16 to government as a tax payee so our payment module has to submit form 16 data to Government exposed API but government API has certain rules and data structure for submitting form 16 data, so although government API is downstream it has total control, our Payment module should communicate with down steam in such a way so it can fulfil downstream rules.

The customer-supplier relation works best when both the parties upstream and downstream are aligned with the work both party agreed upon the interfaces and change in the structure, in case of any changes in the contract both parties will do a discussion synchronize their priority backlogs and agreed upon the changes, If one party does nor care upon another party then every time contract will be broken and it is tough to maintain a customer-supplier relationship.
Conformist: Sometimes, there is a relation between two parties in such a way that downstream team always dependent on an upstream team and they can't do a mutual agreement with upstream about requirements.  The upstream is not aligned with downstream and does not care they are free to change there published endpoint or contract any time and not taking any request from downstream. It is happens when Upstream team is an external system or under a different management hierarchy , and many downstream systems are registered with it so it can't give a priority to any downstream, rather then all downstream system must be aligned with upstream contact and data structures if upstream contracts or data structures change it ps downstream responsibility to changes accordingly.
Say, In our online Student registration app we have a free tutorial module where all students or other application can consume our free tutorials and embed them in their application, so here out free tutorial module acts as upstream and independent of any other third party app who consumes our free tutorials , we can;t give any priority to them and we don't have any contract with them if we change the contracts or data structures it is other third parties duty to change their application accordingly to consume our free tutorials. Other parties are acting as a conformist.

Anti Corruption Layer: When two system interacts if we consume the data directly from upstream we pollute our downstream system as upstream data structure leak through the downstream so if the upstream become polluted our downstream too as it imitates the upstream data while consuming. So it is a good idea while consume data from third party or from a legacy application always use a translation layer where the upstream data translate to downstream data structure before fed in to downstream in that way we can resist the data leakage from upstream, if upstream contract changes it does not pollute downstream internal system only Translation layer has to be changed in order to  adopt new data structure from upstream and convert it into downstream data structure, this technique is called Anti-corruption layer. Anti-corruption layers save the downstream system from upstream changes.
In our application Notification module can implement an ACL while consuming data from payment module so if payment module data structure changes only ACL layers affected.

Open Host : In some cases, your Domain API needs to be accessed by many other services like our Free Tutorial Publisher module, Many external or internal domains want to consume this service, so as Upstream it should be hosted as a service and maintains a protocol and service contract like REST and JSON structure so another system can consume the data.
Published Language: Often two or more system receive and send messages among themselves, in that case, a common language will be needed for the transformation of the data from one system to another like XML, JSON we call that structure as Published language.
The holistic  view of our Student online registration app in terms of context Map

 Conclusion: Context Map is a very important exercise to realize how one domain communicate with other, It gives a proper view of the organization structure, how different domains are distributed, how domain owners are dependent on each other? What is the relationship between team structure? Can they be aligned while developing a feature, based on all the parameters Integration architect can adopt a suitable integration pattern to integrate domains? Prior to designing the integration solution, always architect has to define context map to understand the relationship and structure of the teams based on that Architect can choose the best possible solution.

Bounded Context in my view

In this article, I will share my view about Bounded Context,
What does it mean,?
Why is it required?
The connection between Bounded context and Microservices.
I will try to keep it simple, and this article targeted to that audience who will hear the term Bounded Context while developing Microservices but having a hard time to understanding the Bounded context concept.
Before deep dive into Bounded Context in terms of DDD(Domain Driven Design), Let's understand what is the meaning of that in the real world.
We know the human is the most intelligent species and created different countries for the ruling. But Question is Why they created different countries or Logical Boundaries? In what basis Boundary has been drawn between two countries,  before Human civilization, in the Earth, we only have land there is no concept of country.
One compelling answers come to my mind is that to separate the administration, culture, laws, economics, so each country abstracted its people from other countries unless it is an impossible task to create one Unified culture, language as in ancients time different tribes has there own languages and cultures.
In the same country, there are some predefined rules, language, style every citizen follows. They understand the common language, aware of laws, currency, style so as a brief I can say, Citizens are sync with each other in a country and country has one Unified culture which every citizen follows and understand.
In programming, We apply Bounded context in the same manner, to separate different models/subdomains  from each other in a Domain/Problem space, In a Domain-driven design --Strategic design part,  we introduce Bounded context so in a certain context a model has a certain meaning like the countries where for a particular country--ceratin language, currency has specific meaning, But in a different country that currency or language is not understandable, Because it has no meaning/different meaning respect to that country. Like the word Fool, In English it means Stupid but in Bengali it means Flower !!!!
So If we consider Country as a Bounded context, and language/currencies as a Model inside that context we can easily map the concept of the domain model in a certain bounded context. The model has some meaning for a Bounded context but the same model has no meaning/different meaning for another Bounded context, So by Bounded context, we create a logical boundary where the model and business terms have a certain meaning and the Bounded context separate/hide the models from the outer world. All communication should be done via API. So it is obvious that under a Bounded context -- model and business logic maintains a certain law and maintain its own persistence storage and that is not directly accessible to other Bounded Context.

BoundedContext Communication: Any design has two common parts, abstraction of the data model and communicates with other parts of the system. By Bounded context we separate the data model in a simple term abstracting the commonalities in the business but How one Bounded context communicate with others?
Here the concept of Context Map stepped in, Using Context map we can discover How one Context depends on other Bounded Context, Like are two Context has strong dependencies. or one domain sends a confirmation message to another domain(Conformist) or may use a shared kernel/Shared model, I will talk about Context map later in a separate article, But as of now, you can think context map is for communicating clearly between Bounded Contexts.
At this point, I believe you have a fair bit of idea what is a Bounded context, But still, if you have questions How it fits in Architecture? go to the next paragraph.
Let say we have to design Online Student management system where Student can register to the site choose course accordingly, Pay the Course fee and then he will be tagged to a batch and Teacher & Student is notified about the batch start date and time slot.
As an Architect, you have to identify the bounded context of the different domain related to this business logic.
If we divide the business logic based on related functionality we can found four basic functionality
1. Registration process: Which takes care of Registration of Student.
2. Payment System: Which will process the Course fee and publish online payment status.
3. Batch Scheduling: Upon confirmation of payment,  this function checks the Teacher availability, batch availability and based on that create a batch and assign the candidates or update an existing batch with the candidate.
4. Notification System: It will notify Teacher and Student about the timings and slot information.

So, There are  4 bounded contexts Registration, Payments, Scheduler, and Notification.
Now let's dig down How each Module represents Teacher and Student and Course Models.
Registration process: It only wants the Student information and it needs it demographic information like Name, age, sex, address and which course student chooses.
There is no mean of Teacher in this context
Payment System : It treats Student as Candidates In Payment System only Student/Candidates financial information is required like Account number and based on the course fees it deduct the amount from given account, So here perspective of a student is totally different, Information needed in payment Service is totally different from Registration although Payment system may need few pieces of information like name, address of the student those are very minimal information.
The term "Teacher"  is not valid here, In payment System Teacher treated as Faculty and they can be permanent or Contractor based on the Faculty type Payment System choose the payment calculation either per hour basis or per anum basis.
Batch Scheduling: In case of Batch Scheduling System, it needs bare minimum information from Teacher and Student like name, Address etc. But it needs detailed information, of Course, Batches under the Courses etc.
Notification System: For Notification System, we just need the Teacher and Student email address or Phone number and name nothing else, And it needs the name of the Student management system and Course details, here Student management site acts as Sender and Teacher and Student denotes as Reciever.



Till now we have seen,  same Domain Objects Teacher, Student, Course have different meaning and use-cases for different Context, This is the beauty of Bounded Context ,we have multiple canonical models for same domain Object based on different context, So developers, Business, user are always in the same page when they are talking about a context, the concept of ubiquitous language is woven here, using ubiquitous language DDD create a unified system where every participant understand the language based on the context.
Now, the common question is why the Bounded context term is so popular in Microservices?
To answer this questions first we have to understand that DDD is applicable for Monolith as well as in Microservice, But in case of Monolith, it is vaguer and more of a logical segregation so only good developers can see it. The main reason is in monolith we have a single giant codebase, may we break it multimodule based on DDD create ACL/Translator when one module talks to another but still it needs other modules as dependent jars to invoke its method. Another point is as this is a single code base and multiple coders working on them so some not so skillfull coder can pollute the boundary or domain Object, Architecht can't create a physical boundary based on Bounded Context, But in Microservice architechture it is inherent as Microservice said that rather than a large code base we can create Small services which have it own code base and services are talk to each other through API or messaging, so It clearly says that understand the Business Domain break the Business logic in to multiple Bounded Contexts and each Bounded Context will be a separte codebase and they comuunicate through Context Map, To design the Context map you have to design API carefully, may you can use Port and Hub architechture So your code under the Bounded context is not comminicate with Outerworld and never polluted. Microservice offers this type of strong segregation of Bounded Context. Bounded Context is more visible and understandable in the context of Microservice.
Conclusion: Bounded Context is the basic needs, when you are trying to break a large business logic it helps you to understand how different part of the system use domain objects in a different manner with different terminology. Bounded Context is just a view to properly organize the business logic based on functionality but to make the business logic works --  communication between Bounded context needed, and it uses Context Map for the same. In my next article, I will discuss Context Map.

5 great points why you use event source solutions?

The Event Sourcing Pattern


Joe has a habit whenever he did some transaction by his Debit card he used to write them in his Personal Diary so he can track his transactions. Joe is not a technology savvy and not able to check account statements online.
At the month end, his bank SMS him his current balance but he immediately notices a discrepancy between current savings what bank shows and as per his calculation based on the Diary. He immediately calls Bank helpline and arguing about the discrepancy. Then the bank sends him an Account statement with all transactions recorded.
When he is trying to match transaction records with his diary he understood one transaction not in the Diary as that day he was so sick, he thought it to write it next day but somehow forgot.

But the question is what we can extract from this story?
If we look minutely we discover one fact that Bank always stores all the events/transactions happens on the Account. Like Account creation, credit, debit etc. and the current balance is nothing but the outcome of those transactions. So what I meant to say is that account balance is not a fixed column in a database rather than it is a derivative/outcome of the transactions/events what were applied on the Account.We called it Event Sourcing.
Now think what we generally do in software if we credit or debit any amount we just add or subtract that amount from current balance and update the account with new balance right.
So we have the current state but lost the information how that state is achieved some system uses Audit trail still it is not fully deterministic. So anytime anyone challenges the system this is not the desired system state we don’t have any solid proof other than pleaded to them that system can not be wrong. But if you maintain that history or cause of the state changed like Bank then you just give them the History and asking to check -- a solid way to store proofs.

This is a very common story may anyone of us gone through the same and then look the Account statement for doubt clearing.
Technically what is Even Sourcing?

Event Sourcing is a technique by that we store all the changes of application state as a sequence of events. we can rebuild the state anytime from those events, also can query on the events to construct the desired state.

So the two key benefits are
1.we store all the events in a sequence which enables huge opportunities.
2.The state is the derivative of events so we don’t have to maintain state in the database rather we can programmatically derive state based on the event.

Now this opens a new direction that we don’t have to persist state rather we can derive state and it bring many advantages I will talk about 5 such advantages.


  1. State Rebuild :  As we stores every event applies on an application object, we can create a blank /initial application object and apply every event in the same sequence it applied will bring the same state, so anywhere any point of time we can rebuild a state from events. So systems must have a mechanism to apply event, Then you can rebuild a state if the state is blown up for some reason. One may argue if your application state derives from millions of events applied on it, so computing all events may take time and also storing all events need a big storage area. but the fact is nowadays memory are really cheap also we can have TB of in memory space so computation is also faster, alternatively, we can store snapshot i.e milestone of the state and apply event and rebuild state from latest snapshot.



event source
2.  Temporal Query : Event sourcing is perfect for Auditors. Business analysis team always want to see the past state so they can compare the growth or loss or any valuable statistical data so they need the flexibility to query the system in all possible way to collect statistical data. So If system has a feature to build the past state by passing parameters then analyst team will be delighted and the System which maintains all the state they can easily rebuild /compute the state by the parameters provide by the analyst team say analyst want to see the Account details for 10th December 2016, by event sourcing we can fetch all events till 10 the December and apply them in sequence to build the state and return the result to analysts -- easy job isn’t it.

Add caption




3. Comparing State : Sometimes in a complex system, you need to know if events were applied in different ways what would be the outcome and how much deviation it cause from the current state say, A bank saving account interest rate is 8% previously it was 8.5. Now if the bank wants to know due to the decrease of the interest what is the actual amount bank benefits so they will replay events of 8.5 percents in all accounts and compare the state with current state to know the actual benefits although it is not very easy to implement but we can.



what is event sourcing





4. Debugging State : Suppose there is a bug in production system and we need to debug why the bug happens by event sourcing it is very easy like copy the Account in Dev environment then change the Log level to Debug and apply event one by one in the sequence and check the outcome is predicted or not ,if not then  found the Event and check how it applies to change the application state to found the defect.



event source solutions






5. Future Prediction :  In some Business domain it is important task to analysis what will be outcome if we take some business decision, if the outcome is successful they will take the decision,But in a naked eye it is impossible to predict the application state as different services are interlinked with each other and based on one event they can change, dependent services are subscribed to certain events when that event occurs they take action on basis of event value.  say A bank’s stock share worth is 8 INR but bank analysis team predict  within 1 month it will be increased to 12 INR and they have moreover 30K stocks are public so analysis team wants to know what will be the effects of the application state if stock worth is 12 INR so they will run some ad-hoc future events on top of current state  based on two criteria.
Taking per stock as 12 INR
Taking per stock as 8 INR
Then compare two application states to find out what are the effect of this stock value increase for each interlinked services.





event sourcing benefits

Conclusion : Some systems are inherently Event sourced like Version control (GIT), Banking application, Order Tracking application etc. but we can implement the same in general system also.Using Event sourcing you can easily back and forth you application state by replaying events and state cloning into any environment is just a matter of time but the Irony is, This pattern not used broadly in industry.

3 wise men on Tell Don't ask

A story on Tell Don't ask Principle

wisemen.jpg

John, Doe, and Marcus are three good friends. They have over 20 years of experience Java/JEE stack and working in IBM, Cognizant and TCS respectively. They have immense experience in design pattern and all the new technologies and respected by their colleague for Exceptional insight on the Technology Stack.
They are planning to go for a vacation in the upcoming weekend to enjoy their spare time with lots of Burger, whiskey, and cooking. John has an Outhouse in a village so they planned to go there by driving.
At last, the day came they pack their Beer, Whiskey, and Burger and headed towards John outhouse it was far away from Town. At evening they reached the outhouse and prepare some snacks for their whiskey and sit together in a round table to enjoy Chicken roast and Whiskey.
Suddenly the power cut happens, The room is so dark that no one can see anything, from outside they can hear the Call of Cricket, Marcus put on his mobile flashlight, now they can see each other.
Doe breaking the silence by saying,
“Oh well, this ambiance is perfect for a horror story can anyone share any real life experience?”
Marcus replied in a witty way
“Umm No, I believe all we are from town and busy with IT industry so sorry can not share any horror experience but can share some Java experience which still frightened me”
John and Doe’s Architect instinct flashed with this proposal.
They said, “ Oh yes what would be more good to discuss about something which frightened us an Architect in this ambiance, it is same as Horror Story :).”

Marcus slowly demonstrated the problem.
Marcus: As an Architect when I design a solution for a problem it always frightened me what we encapsulate and what portion we expose to our client program?
John and Doe Nodded their head.
Marcas Continue with his speech,
There are lots of OOPs principle which says how judiciously you can encapsulate your classes or API from outside world.
Take an Example, The  Tell Don’t Ask principle, It says us always tell to Object, in a layman term instruct Object what to do never query for an internal state and take a decision based on that because then you loose control over the object.
Take a simple example suppose I want to write a Parcel Delivery Service and there are two domain Objects Parcel and Customer so how should we design it.
If I write following code fragments

/**
*
*/
package com.example.basic;

/**
* @author Shamik Mitra
*
*/
public class PercelDeliveryService {
   
   
    public void deliverPercel(Long customerId){
       
        Customer cust = customerDao.findById(customerId);
        List<Percel> percelList = percelDao.findByCustomerId(customerId);
       
        for(Percel percel : percelList){
           
            System.out.println("Delivering percel to " + cust.getCustomerAddress());
            //do all the stuff for delivery
        }
       
    }

}


According to Tell Don’t Ask it is a violation and should be avoided. In Parcel Delivery Service I try to fetch or ask Customer Address so I can perform the delivery operation so here I query the internal state of the Customer.
And why it is dangerous?
If later if the delivery functionality change says now it also include an email address or mobile so I have to expose these details so exposing more and more internal state think about the other services they may also use the same email address or Customer address. Now If I want to change the Customer Address return type String to Address Object then I need to change all services where it has been used, so a gigantic task to perform and increases risk factor of breaking functionality. Another point is as internal state is exposed to many services there is always a risk to pollute the internal state by a service and it is hard to detect which service changed the state. In one word I loose the control over my object as I don’t know which services use/modify my Object internal state. Now if my object is used by the Internal services of a monolith application I can search the usage in IDE and refactor them but If the Object is exposed through an API and This API used by other organization then I am gone, It really hurts our company reputation and as an architect, I would be fired.
So I can say

Action: More you Expose Internal state
Outcome:  Increase coupling, Increases Risk, Increase Rigidity.


Now again look the solution I provided,
Doe chuckled and guess which point Marcus trying to make so he interrupted him and start saying.
Doe: So Marcus you want to tell if we follow Tell Don’t Ask principle then there are couple of ways we can refactor the problem
1. make an association between Customer and Parcel . and it would be lazy loaded and deliver method should be in Customer Object so from the service we call deliver then deliver method fetch parcel list and deliver it, so if the Internal return type change from String to Address only “deliver” method should be affected.
Like this,
/*
*
*/
package com.example.basic;

/**
* @author Shamik Mitra
*
*/
public class ParcelDeliveryService {
   
   
    public void deliverParcel(Long customerId){
       
        Customer cust = customerDao.findById(customerId);
        cust.deliver();
    }

}

public class Customer{

    public void deliver(){
        List<Percel> percelList = getPercelList();
      for(Percel percel : percelList){
           
            System.out.println("Delivering percel to " + this.getCustomerAddress());
            //do all the stuff for delivery
        }
       
    }
}



By doing this I maintain Tell Don’t Ask principle properly and decreases the risk of exposing internal state and free to modify my class attributes as all behaviors are tied locally with attributes a nice way to achieve encapsulation.
2. We can create a command Object where we pass the Parcel details and pass the command object to Customer Model, the delivery method extracts the Parcel list and deliver it to the respective customer.
But both policy breaks another principle that is Single Responsibility Principle, SRP(Single Responsibility Principle) says A class has only one reason to change.
But If I think in a reverse way, why we write Services? Because each service does one job like Person Delivery Service responsible for “delivery parcel related “ operations so it maintains SRP and this service only change if there are any changes in Parcel Delivery mechanism and if it breaks other services will not be affected unless other services depend on it.
But according to Tell Don’t Ask all Customer related behaviors should be moved into Customer class so we can tell /Instruct/command Customer class to do a task. So Now Customer class has much responsibility because all Customer-related service code now goes into Customer Model. So Customer has more reason to change so increase the risk factor of failing.
So Now we are back in the same problem risk factor.
If exposing internal state then the risk for modifying attribute if move all behavior into a class then the risk of modifying functionality break the system.
So SRP and Tell Don’t Ask principle contradict in this context.

John: John nodded his head and started with his husky voice, Yes this is really a problem
not only this, If we want to implement a cache in a service or want to implement Aggregation function like Percell delivery rate charge according to distance or Account type, Find most parcels sent to a locality we use Aggregator service where we ask for internal state and compute the result. So often we break Tell Don’t Ask principle. Even as per current trend, Model Object should be lightweight and should not be coupled with each other. If the business needs an information which distributes over multiple models we can write an aggregator service and query each model and compute the result , so we querying internal state. Think about Spring data.
Now If we look in another perspective, according to the Domain-driven Design, In a Parcel Delivery Context (Bounded context) is Customer responsible for delivering the parcel?
Absolutely not, In that context Delivery Boy is responsible for delivering the parcel to the customer. For that Delivery boy needs Parcel and Customer Model, and in that context only Customer name and Address details required and for parcel Id, parcel name will be required so as per DDD we create an Aggregate Model DeliveryBoy where we have two slick Model Customer and Percell because in this context we don’t need customer other details and parcel other details like customer account details, Customer birthdate etc, Context wise model is changed so no one big model for customer where all attribute and behaviour resides rather small slick models based on bounded context and an Aggregate model querying these slick model and perform the work.
By doing this we can mix and match SRP and Tell Don’t ask. For a service perspective we only tell /command DeliveryBoy Aggregate model to do something, so Service maintains SRP and Tell don’t ask, Our Aggregate model also maintain SRP but querying Customer and Parcel Model to do the operation.

Like



/**
*
*/
package com.example.basic;

/**
* @author Shamik Mitra
*
*/
public class ParcelDeliveryService {
   
   
    public void deliverParcel(Long customerId){
       
        DeliveryBoy boy = new DeliveryBoy();
        boy.deliver(customerId);
    }

}

public class DeliveryBoy{
    Customer cust;// Context driven model
    Percel percel;
    public void deliver(Long id){
        //do stuff
//load customer slick model
//load Percel slick model
//Deliver the same by quering

        }
       
    }
}

Marcus joined and says let's take one step further as DDD insists  Microservice, so in Microservice we try to break a monolith using functional decomposition( A function is a Bounded context in DDD) so one service doing one task maintains SRP principle and if we needed and information which distributes over multiple services we create an Aggregator service and querying individual service and do the task so Microservice often breaks Tell Don’t Ask
Doe joined and says So there is no silver bullet and not all principles are good in all context, Based on the context you have to judge which principles you follow sometimes you need to compromise, may for a specific principle viewpoint your code is bad but for a given context it is optimum.

Principles are generic and they are context free but real life solution are based on context so fit principles based on context not the reverse.

In the meantime Light comes, so John said here we are for fun let stop the discussion and concentrate on Whiskey and Roast !!!!
Everyone agreed and change the topic.
Conclusion : As a Narrator, My question to all viewers, what do you think about the talk they did, is there are any points they left off which needs attention while designing?