Search code examples
c#architecturedomain-driven-design

Implement application level and UI level interfaces in domain objects


I'm building an application that allows engineers to configure "rigging" (i.e. cables between something you lift, and the crane you lift it with). We're a remote team of two, communication is a bit sparse due to time-zones and other projects. I have a question on how to best structure the domain layer, and specifically whether or not it would be considered best-practice to use interfaces to allow us to work more independently.

The heart of the app is a domain model of the "rigging", which is a deeply nested class hierarchy. The data in these classes is used for two things:

  • Rendering in the UI
  • Solving (i.e. calculating loads)

If I take things like layered architecture literally, I'd say just implement the 'Rigging' as POCO, and have the Rendering (UI layer), and Solving (Application Layer) depend on those classes.

However, I run into two issues:

  • Rendering and solving on the one hand, and the logic of constructing the domain elements on the other are developed by different people
  • Rendering and solving each use different parts of the data. The domain classes are already quite large with the logic to construct them and enforce consistency. This makes it difficult to see for the person developing the classes what properties are actually depended on by the other parts of the application.

I was thinking the following structure to tackle this:

public class Rigging : IRenderableRigging, ISolveableRigging {
   // Logic to construct and keep underlying data consistent, and 
   // transform underlying data into properties used by rendering and solving
}

public interface IRenderableRigging {
   // Properties needed just for rendering, used by GUI 
}

public interface ISolveableRigging {
   // Properties needed just for solving 
}

Would this be a good approach, an overcomplication, or just straight up a violation of the idea that dependency should only travel down the layers of the architecture?


Solution

  • IDK why this question got downvoted, and I think it has good points. Here are my notes:

    • In the domain layer, it is not allowed to implement defined interfaces in the presentation/application layer.

    • If IRenderableRigging and ISolveableRigging are not part of the Ubiquitous language, you can not reference or define them in the domain layer. All elements of the domain layer must be understandable to domain experts and other stakeholders.

    • To emphasize the issue of the encapsulating coherent properties of the Rigging, there might be a possibility of a bad design. If it has many properties that can be grouped by their meanings (meaning that they are coherent and have a single responsibility), Rigging might consist of multiple value objects. Value objects make large aggregate roots smaller.

    • Always use DTO on the application layer to encapsulate what you need from the domain model. ISolveableRigging might be a SolvingRiggingDto, and IRenderableRigging might be a RenderingRiggingDto.

    • Communication issues on remote developing would not be solved by defining these interfaces. Because even after you create an interface, the responsibility of mapping domain properties will be the issue. These decisions must be taken consciously and shared amongst all team members. You should consider agile practices and emphasize collaboration between team members.