Think Before Coding

To content | To menu | To search

Domain Driven Design

Entries feed - Comments feed

Tuesday, June 23, 2009

Where are my Entities and my Repositories ?

During Evans’ talk at ParisJug, some attendees where surprised that there was no mention of Entities or Repositories

Quite a lot of people where introduced to Domain Driven Design by these aspects and see these as the main advance of DDD.

In contrast, Eric Evans explained to me he had some regrets he placed these patterns so early in the book. Many readers think they know the most important at this point and stop reading after chapter 6.

Actually those patterns are only object model patterns that enable Separation of Concerns and Persistence Ignorance, but can also be used in context that are not Domain Driven at all like CRUD.

Of course, if you want to implement a domain independent of all infrastructure concerns, good OO practices will be required, but those practices won’t make your application Domain Driven (don’t understand that not following DDD would make your design a bad design… you apply DDD if you want and if you need to, but achieving persistence ignorance won’t mean you practice DDD.)

But you’ve more to learn from Strategic Design, Bounded Contexts and distillation of the Core Domain etc.

Friday, June 19, 2009

Strategic Design at DDD Exchange

Gojko Adzik has a post about Eric Evans’ talk at DDD Exchange :

Why do efforts to replace legacy system fail ?

You can also read my previous post about strategic design.

I’m currently working on evolving a large legacy system, and my experience tell me it’s the right way to deal with it !

Don’t try to switch off legacy system. Go along with it using anticorruption layers to protect you elegant core domain.

Wednesday, June 17, 2009

Which model is best ? Thats not the question.

Mercator_1569Those who already read the book should already know this. It’s still interesting for newcomers and you can  send comments if you want !

During his Talk at ParisJug, Eric Evans presented two possible models for Cargo itinerary.

The first one was around the notion of Stops (at a Stop, you unload, then you load), and the second one was around the notion of Legs(you load at the start of a Leg, and unload at the end). An itinerary could be seen as a list of stops or a list of legs.

The question was, which model is best ?

Of course, there is no answer to this question.

The same question was translated to a comparison of maps. First an map of China from the 16th century, and a Mercator projection map.

We should be inclined to say that the second one is best. But the first one was largely enough for the need at that time. And if you inspect the Mercator projection, you can notice that it is not that accurate for some tasks. For example, the Greenland seems abnormally large.

Why do we use Mercator projection then ?

It became the standard map projection for nautical purposes because of its ability to represent lines of constant course, known as rhumb lines or loxodromes, as straight segments.

If you want a map to compare country areas, use a Gall-Petters projection or a  Goode homolosine projection

So the question becomes :

Which model is more useful ?

And for the question to be complete :

Which model is more useful for what ?

To come back to the cargo application, Stops will be useful to produce orders to unload and reload containers from cargos, but legs will be useful if you need to track transport location or change routing during transport.

You’ll have noticed :

It depends on the context

When DDD should be considered ?

This is a recurring question on the DDD yahoo group. And there was a simple explanation during the ParisJug talk.

DDD is not a silver bullet for all application development, it just helps to manage complexity when the complexity comes from the domain.

No need for DDD when working on a technical application or a small application with few interactions.

You could benefit from DDD when your application looks like the Cargo sample :

  • Route containers based on transports availability
  • Take cost and time into account
  • Know where are the boats
  • Organize loads and unloads
  • Manage container storage (emit order of missions for employees on site)
  • Provide container tracking and tracing to clients
  • Transports can be late, manage it
  • Transports can be canceled, manage it
  • Contracts can be changed, destination can change
  • Containers can be incorrectly routed even if emitted orders where correct, manage it.
  • Manage taxes
  • Manage time zones
  • Manage currencies
  • Manager constraints and local rules on dangerous containers contents

In this kind of application, the complexity doesn’t come from an Xml web service or a database schema. Even without taking account any technical concern, it is complex !

So there is a simple rule of thumb to know if DDD could apply (independently from the size of the project) :

Try DDD if Domain Complexity >> Technical Complexity

In other case you can just go with your preferred classic architecture.

Tuesday, June 16, 2009

Met Eric Evans at ParisJug

IMAG0387 The ParisJug organized a DDD event yesterday in  Paris presented by Eric Evans, the author of Domain  Driven Design himself.

He’d come in France ten years ago, but never made a presentation about Domain Driven Design here yet.

Thanks to Antonio and Nicolas and the others and who organized this presentation in 4 days. You can find a summary of the talk in French here.

Putting the model to work

It was the title of the talk. I’ll not make a full report since it was mainly what’s in the book for those who had not grasped the concepts of DDD yet.

I’ll talk about important topics of the content in following posts.

Diner with Eric Evans and Jug guys

After the presentation, we moved to a restaurant with Eric Evans, the organizers and other attendees. I had the chance to be at the same table as Eric, so I had the opportunity to talk with him about a lot of things.

He’s not at all the Pattern Guru kind. Very careful to let you understand he’s not found a solution to your problems, that you’ll have to work, but that his experience and analysis can help to grasp things a bit more clearly. He’s constantly working hard on several project to get more experience and set his knowledge and experimentation against different contexts.

I’ll also talk about part of our discussion in following posts.

Tuesday, April 28, 2009

Strategic Design

I was looking yesterday at Eric Evans’ talk at the Øredev conference last November.

You really should see it to understand better one of the most important part of the DDD book that is difficult to grasp on first reading.

I’m currently working on a small company that had a problem with scaling their system. The existing system was working correctly but was going to stall in both performance and evolution perspectives.

When we arrived, the plan of the preceding head of development was :

‘We need to restart from scratch, let’s specify everything, then code a clean version 2.0 in two years, and switch the legacy system off.’

Of course it was expected to fail.

And even if it succeeded, after two years, they would have got the same software that two years before.

It could be cleaner, but who cares ?

When you’ve lost two precious evolution years, for a promising startup, count it as dog years.

When we took control of the situation we planned the following :

  • Extract the core business value of the software.
  • Spot where you need new features.
  • Develop new features as if it was in a clean environment.
  • Develop anti corruption layers to hide the legacy system behind clean interfaces.

This way you start to work on new business value now, you make the model cleaner over time, and you have benefits of the working legacy system instantly.

Don’t waste your time recoding what is already working.

Act to add value to your business.This is where your craft should go.

Wednesday, April 8, 2009

Back on Repositories and Paging. Introducing reporting.

I had quite a lot of comments on my previous post on repositories and paging, and there’s a lot of people coming from google looking for answers… It’s sign that there’s no good response to this issue now.

The problem was how paging (a presentation concern) fits into a repository that should have only domain concerns…

And the short answers is… It doesn’t fit !

It doesn’t mean you should forget everything I told you before but there’s a vision change.

There’s something missing in DDD book…

but present in current discussion about DDD. The book provides good building blocks (entities, repository…) but Evans says himself it has been a bit over emphasized. The book is mainly about maintaining and mutating your domain state, not about it’s presentation.

CQS to the rescue

The CQS (Command Query Separation) principle proposes to decouple Commands that change the state of the system, from Queries that ask the state of the system.

The repository lies on the Command side, that’s why :

  • It should be specialized to express only mutations that are possible for the system
  • It should not expose presentation concerns like paging

But what’s on the Query side ?

The query side should be far more supple and provide tools to query the state of the domain. It can even be implemented with IQueryable interfaces to provide that flexibility. Asking for pages in this area is natural since you just want to query a part of the domain state.

The goal of all this is to report the state of the system. So Reporting is a good name here.

You can read Greg Young’s DDDD posts to see where CQS can lead : Write only domain model (Commands) and rich scalable distributed Query mechanisms using messaging.

There’s no clear guidance yet in this field but I’m still investigating. The flexibility of a reporting service in the domain layer is still a huge gain to understand where each concept fits.

Thursday, March 12, 2009

QCon London 2009

Today, there's a full QCon London track dedicated to Domain Driven Design.

Eric Evans exposed this morning what he's learned about DDD since the book, and lots of interesting things.

Gojko Adzic posted a report of Evans' talk.

The whole slides should be available on QCon site shortly.

You can also follow in on twitter through Richard Banks reports.


Wednesday, March 4, 2009

How *not* to inject services in entities

syringeI’ve seen lot of people asking where and how to inject services in entities. The services in question are often repositories by the way…

The response is simple :

 - DO NOT inject services in entities !

- Ok I see, you’re against dependency injection

- NO, I'm not against dependency injection, I use it a lot.

- You can still use a static service locator…

- I avoid service locator when I can, especially when the service locator must be static…

– So you’ll get an anemic object model !

- I don’t think so.


Injecting services in entities is wrong

You’ll find me a bit presumptuous, but I say it again : Injecting services in entities is wrong.

Nesting objects is not a problem from an OO point of view, but we’re talking about a special kind of objects, entities.


Entities are all about their state management, and this state management can require several objects.

  • Code infrastructure objects like lists or dictionary to handle collection of data,
  • Object oriented constructs to leverage code maintenance techniques like strategies.

Entities don’t have to be classes with public setters and getters… you should even avoid this to keep you entities in a consistent state.

But there is no reason for an entity to keep a reference on a service, since it’s not part of its state.

There are usually three situations in which people thinks they need it :

  • Lazy loads
  • Relations
  • Behavior methods

Let’s review each point…


Lazy loads

Sometimes, an entity property is heavy to load and is not required by all code paths. In this case, loading it upfront can lead to performance problems.

The usual way to work it out is to hold a reference to a data access object or a repository and to load and cache the requested data on demand.


 Using a data access layer object in the entity is clearly a break of persistence ignorance, but using a repository is not a better option.


The repository is a way to abstract persistence in the model, but it’s still a persistence concern even if modeled in terms of domain terms.

I’ve already posted about ways to solve this problem in Lazy load and persistence ignorance and part 2.



I was twitting yesterday with Kyle Baley about the need to have an Event repository in the Users entity. He wanted to get the User Team for the current event. I think you don’t need more context to understand the problem.

The User did not know about the current event so it needed the Event repository to find it and find the corresponding team.

But why does the User entity expose a CurrentTeam property if it doesn’t know about Events ? There’s something missing here.

The whole picture becomes clearer if you add a Participant entity that embodies the participation of a user to an Event, and no repository is needed anymore since you don’t need a CurrentTeam property on User.

 Make relations clear instead of hiding it in repositories.


Behavior methods

If I have mail message entity and I want a Send method on it ?

Tiding your entity to the service that will use it is not conceptually satisfying. The server that will send the message is a medium and is not part of the entity itself.

It’s seems better to call server.Send(message).

The problem is that you can end breaking the tell don’t ask principle because the Send method will ask the message for each property value. And you can be tempted to put computations that should be in the message entity inside the Send method.


Let’s call Double Dispatch to the rescue !

  • Design a server interface presenting a Send method that take the parameters it need (title, recipients, message body…)
  • Add a SendThrough method to your entity that takes the server interface as parameter
  • Implement SendTrhough so that it computes values to pass to the Send method
  • That’s it.


Here is a small sample implementation :

    public interface IMailService


        void Send(string sender, string recipient, string subject, string body);



    public class Message



        public void SendThrough(IMailService mailService)


            string subject = isReply ? "Re : " + title : title;

            mailService.Send(sender, recipient, subject, GetMessageBody(content));



The entity is not tied to the service before needed. So no need for injection.


Is injection useless ?

There is no problem to inject services with other services, and it’s even easier since services have no state, they only need their dependencies in constructor, and to my opinion it’s the cleanest injection mode.

Usually domain services will need infrastructure services dependencies, and in this case a dependency injection framework can make things easier.

Following the preceding advice, you’ll never need to use your dependency injection framework as a service locator, and you’ll never have to perform buildups on your entities, and you’ll feel much better.


What’s your way to deal with it ?

For now I’ve always find a way to get rid of services inside entities, but I really would like to hear cases where you’re stuck with it to see if another way is possible, or cases where you think there is really a good reason to go this way.

Tuesday, February 24, 2009

Domain Driven Design Step By Step

Casey Charlton is moving his DDD series on a wiki site so that every body can put it’s personal touch.

You can find it and participate at :

Expect me to write there !

Sunday, February 8, 2009

Lazy loads and persistence ignorance (Part 2)

In the previous post, I introduced a class to manage function injection for lazy loads to enable persistence ignorance.

Chris was asking where the builder I was talking about should be used, and I tumbled on a StackOverflow question asking how to make lazy loading without using classes like Lazy<T>...

I'll discuss the second part first.

There is a good way to make lazy loading without using classes like that. You can use proxies.

There are two main ways to make transparent proxies

  • by creating dynamically a derived class using Reflection.Emit
  • by creating a transparent proxy

Still there are some drawbacks with both approaches. For the first one, all your members should be made virtual, for the second your class should inherit from MarshalByRefObject. In all case you should then take care not to mess up between proxies and underlying classes.

The main critic to refuse to use Lazy<T> class is usually that it's not a domain concept, and that it leaks persistence concern in the model.

I reject those critics.

Have you ever seen someone criticize List<T> or Dictionary<,> because it was not a domain concept ? We're writing OO code, and we can use basic tooling to make our models expressive. IEnumerable<T> and Linq to objects are good examples of these useful tools.

And I don't consider that Lazy<T> is a persistence concern. It expresses that the relation between entities is a bit more loose than others. There is nothing in the Lazy<T> signature that ties your entity to any persistence concept. You just provide a way to give the value of the property when needed rather than at construction, but this choice comes from outside of your entity.

And at least it becomes clearer than with derived proxies where the C# keyword virtual is used to express something but tries to hide it in the same time.


For Chris question, I use the builder in the repository.

The repository is responsible for retrieving entities from the data store. The reconstruction of objects is a bit different from the construction. This is underlined in Evan's book in the chapter Factories / Reconstituting Stored Objects.

In my data access layer I use a IDataBuilder<T> interface that represents a service that can build an object of type T from a IDataRecord. This is when I work directly with the ADO.Net and stored procedures.

    public interface IDataBuilder<T>


        T Build(IDataRecord record);



I also use a class that encapsulate the access to the stored procedures (or queries if you don't want to use stored procedures).

    public class DataAccess


        public UniqueResult<Entity> GetEntity(Guid id);





        public MultipleResult<Entity> GetEntities()






UniqueResult<T> and MultipleResult<T> provides a methods that take a builder to read data records :

    public struct UniqueResult<T>


        public T With(IDataBuilder<T> builder)






    public struct MultipleResult<T>


        public IEnumerable<T> With(IDataBuilder<T> builder)






In your repository implementation you can then use all this :

    // The concrete repository interface that belongs to the domain

    public interface IEntityRepository : IEnumerable<Entity>


        Entity this[Guid id] { get;}

        //.. other methods



    // the implementation that is not part of the domain

    // an that is pesistance dependant.

    internal class EntityRepository : IEntityRepository


        private DataAccess dataAccess;

        private EntityBuilder builder;


        public EntityRepository(DataAccess dataAccess, EntityBuilder builder)


            this.dataAccess = dataAccess;

            this.builder = builder;



        public IEnumerator<Entity> GetEnumerator()


            return dataAccess.GetEntities().With(builder);



        IEnumerator IEnumerable.GetEnumerator()


            return GetEnumerator();



        public Entity this[Guid id]


            get { return dataAccess.GetEntity(id).With(builder); }




The last part is in the implementation of the builder.

    internal class EntityBuilder : IDataBuilder<Entity>


        private DataAccess dataAccess;


        public EntityBuilder(DataAccess dataAccess)


            this.dataAccess = dataAccess;



        public Entity GetEntity(IDataRecord record)


            var id = (Guid)record["Id"];

            return new Entity(


                Lazy.From(() => dataAccess.GetSubEntity(id)));




Of course, the repository implementation, the DataAccess class and the builder are all internal to the data access implementation. It can be in a separate Assembly or internal in a sub namespace of the main assembly depending on you module separation preferences.

When using linq, you simply don't need the DataAccess class because you can query the DataContext directly. But you can use the same pattern.

The main point is still that your Entity object knows strictly nothing about what's going on there.

Saturday, February 7, 2009

Lazy load and persistence ignorance


I often see questions about how to make lazy loads in entities, and wether using dependency injection for it.

The usual response is something like this :

    class Entity


        private Guid id;

        private SubEntity subEntity;

        private IDataService dataService;


        public Entity(Guid id, IDataService dataService)


   = id;

            this.dataService = dataService;



        public SubEntity SubEntity




                if (subEntity == null)

                    subEntity = dataService.GetSubEntity(id);


                return subEntity;




As you can see, your entity is seriously tied to your persistence problem now. Even if it accesses the persistence layer through an interface, it is not persistence ignorant anymore.

The smell is that you cannot create an in memory instance of your entity anymore without worrying about data access.

Should you sill inject the data access service, or is it useless and you should leave it null ?

So believe me : do not inject data services in your entity.

Now, how can we still have the lazy load behavior ?

Through injection. But not dependency injection, I use execution inversion of control through delegate injection.

If you give to your entity a function that will return the value when asked, it's as if you gave the value.

Let's encapsulate this in a small class :

    public class Lazy<T>


        private T value;

        private Func<T> loader;


        public Lazy(T value)


            this.value = value;



        public Lazy(Func<T> loader)


            this.loader = loader;



        public T Value




                if (loader != null)


                    value = loader();

                    loader = null;


                return value;




        public static implicit operator T(Lazy<T> lazy)


            return lazy.Value;



        public static implicit operator Lazy<T>(T value)


            return new Lazy<T>(value);



Then you can use it like this in your entity :

    class Entity


        private readonly Guid id;

        private readonly Lazy<SubEntity> subEntity;


        public Entity(Guid id, Lazy<SubEntity> subEntity)


   = id;

            this.subEntity = subEntity;



        public Guid Id { get { return id; } }


        public SubEntity SubEntity


            get { return subEntity; } // implicit cast here



The code is more straight forward, the intent is clearly visible.

One benefit here, is that the subEntity field can be marked as readonly, that is a big improvement because our entity is really immutable now. Actually the Lazy<T> is mutable, but it behaves as an immutable value.

If your entity is not immutable, you can still leverage the Lazy<T> class :

    class Entity


        private readonly Guid id;

        private Lazy<SubEntity> subEntity;


        public Entity(Guid id, Lazy<SubEntity> subEntity)


   = id;

            this.subEntity = subEntity;



        public Guid Id { get { return id; } }


        public SubEntity SubEntity


            get { return subEntity; } // implicit cast here

            set { subEntity = value; } // implicit cast here too



The last part is about how you use it when instantiating the object.

When creating a new instance in a factory (not linked to database) :

            SubEntity subEntity = ...;

            Guid id = ...;

            Entity entity = new Entity(id, subEntity);

Here again, the implicit cast happen to pass the SubEntity as an already loaded Lazy<SubEntity>.

When binding the entity to the database :

    class EntityBuilder


        private IDataService dataService;


        public EntityBuilder(IDataService dataService)


            this.dataService = dataService;



        public Entity GetEntity(Guid id)


            return new Entity(


                new Lazy<SubEntity>(() => dataService.GetSubEntity(id)));



We can use a small helper method to make the instantiation cleaner :

    public static class Lazy


        public static Lazy<T> From<T>(Func<T> loader)


            return new Lazy<T>(loader);



Then you can write :

            return new Entity(


                Lazy.From(() => dataService.GetSubEntity(id)));


Now, the code that instantiate the Entity decides where the sub entity comes from.

The entity has become truly persistence ignorant.

Some would also advice not to use lazy load at all... this is still an option to consider !

Continued in Lazy loads and persistence ignorance (Part 2)

Wednesday, January 21, 2009

Mixing IEnumerable and IQueryable

Marcel posted a comment in the previous post saying that even if returning IEnumerable, the new query clauses would be executed in the database… But it’s not.

If the repository use linq internally and returns the result as IEnumerable, on the other side, consider something like this :

var selectedEntities = repository.GetAll().Where(x => x.Selected)

Where GetAll returns an IEnumerable (that is actually a IQueryable).

The Where extension method will be selected on Enumerable. Be careful, Extension methods are static methods, no virtual call is involved here. The static type of the object decide the selected extension method.


Check in your debugger, selectedEntities is an instance of the Enumerable.WhereIterator internal class.


So when enumerating it, it enumerates its source and returns every item that passes the predicate.

When enumerating the source, here the source use linq2Sql to get the items and creates a query that returns all rows from the database.

The where clause was not executed in the database.

So the Linq provider did not leak outside of the repository.

Monday, January 19, 2009

Repositories and IQueryable, the paging case.

Edit : My opinion on this subject have changed… You can read the full story in Back on Repositories and Paging. Introducing reporting.

The technique is still useful to write the query services, but I would not recommend to implement it on a repository.


When it comes to repositories, people have a hard time figuring how to respect the DDD vision while taking most out of current ORM technologies (Linq and ORM) and not writing too much code – we’re so lazy.civilwar

The war between IRepository<T> generic repositories or not is raging outside, and I took some time to chose my side. Here are the points to consider :

  • The repository is a contract between the domain and the infrastructure
  • The implementation details should not leak outside

In my opinion, the first point indicates that the repository should be tailored to the domain needs. It cannot be generic, or it is not a contract at all.

When writing a contract, details matter !

This doesn’t mean that we cannot use generic tools to access data behind the interface curtain. Linq DataContext and Tables<T> are very sharp tools to implement repositories. And there is a very good post by Greg Young about that.


There is still a point to be discussed though :

Should the repository methods return IEnumerable<T> or IQueryable<T> ?

The IQueryable<T> is part of the framework, and cleanly integrated in the language.

The problem is that its implementation depends heavily on the underlying provider. And it is a really serious leak !

So lets state the question differently :

- Why would we need IQueryable ?
- Because we can add new query clauses, and they will be executed directly in the database.

- What kind of clause would you add ?
- Don’t know… clauses…

- Would it be business specifications ?
- No, these should already be in the repository..

- So ?
- Sorting and Paging ! These are presentation concerns !

- Here’s the point.

Paging is not a recent concern for programmers and there is never enough tools to implement it properly. The main problem is that paging once you’ve got all the data is less that effective. And this is what will happen with an IEnumerable approach.

But let’s ask a two last questions.

Why is paging useful ? Is it really a presentation concern ?

We need paging to navigate through large collection of object, and if a collection can grow enough so that is cannot be embraced in a single query, it becomes a domain concern !

  • When your object collection is known at design time to stay in small bounds but you still want to page it for presentation clarity, there is no real penalty to fetch all and display only a few.
  • But when your collection can grow big, you SHOULD provide a mechanism to retrieve only a range of it, for presentation purpose or simply for batching purpose.

The problem is that if we leak IQueryable, the user can do far more than paging, and problems can arise. So I suggest to use a new interface IPaged<T> that would provide everything needed for paging :

public interface IPaged<T> : IEnumerable<T>



        /// Get the total entity count.


        int Count { get; }



        /// Get a range of persited entities.


        IEnumerable<T> GetRange(int index, int count);



And here is a simple implementation on a IQueryable :

public class Paged<T> : IPaged<T>


        private readonly IQueryable<T> source;


        public Paged(IQueryable<T> source)


            this.source = source;




        public IEnumerator<T> GetEnumerator()


            return source.GetEnumerator();



        IEnumerator IEnumerable.GetEnumerator()


            return GetEnumerator();



        public int Count


            get { return source.Count(); }



        public IEnumerable<T> GetRange(int index, int count)


            return source.Skip(index).Take(count);



Then your repository can return IPaged collections like this without leaking implementation details :

public IPaged<Customer> GetCustomers();


This seems to be a major step in the repository pattern understanding, and it’s underlying war. And you, on which side are you ?

Monday, December 22, 2008

DDD: Specifications

There's an interesting post by Greg Young about Specifications.

I'm currently refactoring some code to move constraints and validation in specification classes, and it really gives a better insight at what is constituting entities and what's not, especially when there are multiple level of constraints (persistence constraints, business constraints...)

Wednesday, December 10, 2008

Wow - Book review - Domain Driven Design!

Ok, I finished Domain Driven Design yesterday. I think I had no such Aha moment since I read Design Patterns eleven years ago...

I thought I was prepared for it, I had read many things to get maximum info...

I had :

I had practiced knowledge crunching on my own for long.

But the book go far beyond all that. It has a deep vision of programming on large scale projects, and give really good insight on difficulties that arise when working on complex systems with several teams. These are really precious pieces of advice.

The pattern presentation of the different chapters, even when those patterns are not implementation patterns but team organization patterns is really helpful and clear.

There is not much about implementation details, but it is not a problem. The principles are not tied to a specific technology or framework. Actually this is even a good point, it leaves the book clean from a specific implementation. Implementation books are aging faster.

You definitely should have this book on your shelf.

Tuesday, December 2, 2008

Domain Driven Design

I had read a lot of stuff about it these last months, and I think I got the essence and the principles.

I've received the blue book today.

I'm sure I'll have matter for blogging these days...

Monday, December 1, 2008

Ubiquity of language... lost in translation ?

I found two collapsing problems :

  • You should use the same language between domain experts and development teams (DDD)
  • You should use English for naming in your code (Design guidelines)

What if my domain experts don't speak English ?

page 2 of 2 -