This document provides an introduction to domain-driven design (DDD) and discusses how following DDD paradigms can help an IT department better achieve business goals and adapt quickly to changing market conditions. It notes that business complexity grows rapidly, and finding ways to meet business objectives is key. The document outlines DDD concepts like the ubiquitous language, bounded context, and layered architecture. It also lists common DDD building blocks like entities, value objects, aggregates, services, factories, and repositories. It then gives an example of starting a DDD implementation with entities and adding factories, services, repositories, and aggregates. The document concludes that improving the domain layer is an ongoing, iterative process aligned with business needs.
3. IT department is a key element to
support such change
• Business complexity grows and changes
quickly!
• We must find the way how to achieve the
goals set by a business!
23. Improve Domain Layer
• Ongoing process of refactoring driven by
Business requirements
• No need for complete overhaul – iterative
process is more aligned with Business needs.
When I was about to create a presentation about recent implementation of Repositories I realised that it would not be understood by our team without some proper introduction to Domain Driven Design. Therefore I decided to make a presentation about DDD instead and use Wiki to describe the processes around Repositories.
Every enterprise must be able to adapt fast in order to survive in the market. Technology changes faster than ever before. Market demand and supply changes in volumes and in structure – constantly.
And an IT department should be key a element to enable such change.But business complexity grows and changes quickly! Legislative changes ... Global Financial Crisis ... Competitors continually launching new products and so on.So we in IT must find a way how to achieve the goals set by the business!
Domain Driven Design offers the solution.DDD is not about technology rather than about business modelling and its transformation into software. It describes the way how to do it and also how to solve common problems.
But do we need another methodology, other processes to follow? Isn't it just some sort of abstract over complication? Let me explain!
Spaghetti code is about processing data instead of building blocks. That means every where the data had been used, the code followed. It breaks the DRY principle and leads to spreading of Business Logic across the whole application.Later we started putting Business Logic into Objects, which was a great leap forward!
Simply following OOP basics does not get the job done right. It can lead to creating of ‘Balls of Mud’ - classes with too many responsibilities which are breaking up the Single Responsibility Principle. Also subclassing/inheritance can be abused instead of using composition.Mixed responsibilities lead to unpredictable behaviour.Such class takes too long to read and understand and even longer to change.
Changing untested code has unpredictable consequences. Untested code is often the cause of: *) application bugs*) creation of Heroes – only the developer who developed the code can maintain it*) barrier for implementation of any new features – nobody wants to change such a part of the system – which leads to FDD
People are afraid of making changes to a code and would rather maintain it in its current state or demand complete overhaul before executing any - even small changes.
There are many ways how to provide business what it requires: Agile, RUP, Lean etcToday I would like to focus on DDD.Domain-driven design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts. The premise of domain-driven design is the following:*) Placing the project's primary focus on the core domain and domain logic*) Basing complex designs on a model*) Initiating a creative collaboration between technical and domain experts to iteratively cut ever closer to the conceptual heart of the problem.Domain-driven design is not a technology or a methodology. DDD provides a structure of practices and terminology for making design decisions that focus and accelerate software projects dealing with complicated domains.The term was coined by Eric Evans in his book of the same title:Domain-Driven Design - Tackling Complexity in the Heart of Software
So what is the DDD?Domain: A sphere of knowledge or activity. The subject area to which the user applies a program – that is the domain of the software.Ubiquitous Language: A language structured around the domain model and used by all team members to connect all the activities of the team with the software. E.g. ‘Invoice Balance’ or ‘Released Pay’Context: The setting in which a word or statement appears that determines its meaning.
User Interface / Presentation Layer: Responsible for presenting information to the user and interpreting user commands.Application Layer: This layer coordinates the application activity. It doesn't contain any business logic. It can hold the state of an application task's progress.Domain Layer: This layer contains information about the business domain - the heart of software. The state of business objects is held here. Persistence of the business objects is delegated to the infrastructure layer.Infrastructure Layer: This layer acts as a supporting library for all the other layers. It provides communication between layers, implements persistence for business objects, contains supporting libraries for the user interface layer, etc.
Entity: An object that is not defined by its attributes, but rather by a thread of continuity and its identity.Example: Invoice, Payroll, Contractor. Identity can be provided Invoice ID or for Contractor by some Customer reference number (not necessarily by database id)Value Object: An object that contains attributes but has no conceptual identity. They should be treated as immutable.Example: CXC_Date - date does not have any identity, but it is distinguished by its value. Another example can be Price consisting of amount and currency. Aggregate: A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. The aggregate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.Example: Invoice and its Invoice Items or Contract and its Contract Rates. Service: When an operation does not conceptually belong to any concrete object, one can implement these operations in services. Service operation is stateless. Example: 'Assign contracts to manager' or 'Calculate Payroll'. Factory: methods for creating domain objects should be delegated to a specialized Factory object so alternative implementations may be easily interchanged.Example: Payroll Builder - to build a payroll requires too many tasks to just make it part of Payroll object itself, therefore dedicated object is required which sole purpose is to Build the Payroll object.Repositories: methods for retrieving domain objects should be delegated to a specialized Repository object so that alternative storage implementations may be easily interchanged. Repositories should provide abstraction of persistence storage to Domain layer. They are not the same as Factories, because process of building and retrieving from repository is completely different. Example: Newly created repositories in PAYX.
It all began when the PAYX/lib folder was introduced. It was a good start to achieving the multilayered architecture – to separate the Model from Views and Controllers. But what went wrong was all the classes suddenly became Entities – they became overcomplicated and unmaintainable, untested and actually untestable.
One day time we started using Unit Testing. Then we realised our current approach is making Unit Testing hard. We replaced static methods or functions with Factories
Later we replaced other static methods with Domain Services. It improved testability and clarity of the Domain, but unfortunatelyServices had too many responsibilities. It led to mocking of methods of the same class during unit testing. This was the reason we implemented ...
Now this is the last part we finally introduced to PAYX. Repositories provide methods for retrieving domain objects from persistence storage and are creating an illusion of in-memory object graph for the Domain Layer. By injecting Repositories we can easy make the unit tests DB independent.
But also we can easily swap persistence storage without affecting Domain!
Good examples for Aggregates in PAYX are Invoice with its Invoice Items or Wree with Wree Items.
As I already mentioned an example is CXC_Date or Contract_Number class.