Daily DDD

From the mouths of lots of DDD practitioners, and from Eric himself, we often hear DDD is hard. In my opinion it would be more correct to say DDD is huge. Trying to understand it from scratch, as a whole, is like trying to understand a huge code base as a whole. It’s impressive and discouraging.

But if we split it in small, organized logical components, it becomes easier. Finally we’ll see these components work well together, but before that we’ll grab only what we can, and that’s fine.

After 5 years practicing DDD, I still discover new things every few weeks. That’s ok, I’m not a DDD expert, and still it brings me a lot in my daily work. I’d like to share it in this post, to show you don’t need to know everything about DDD to get a lot from it.Sans titreBusiness first, code after  

The first great lesson I learned from DDD was : understand the business. Then we can look for the best technical implementation (if any) to solve their problems.

For me it was a real revelation, it changes the posture I had as a developer. I no longer work to do what someone thinks I have to do. I work with the business, challenge their solution and try to find practical alternatives when I believe they are technically wrong.

In my day to day work it means, talking to domain experts to analyze problems, proposing technical implementation aligned with the domain and easy to modify. I welcome changes as opportunities.Business

Problem analysis  

We can solve lots of problems with software, but it’s hard to figure out which problems are worth fixing. Unless it’s an obvious problem (but was it really a problem in this case?), we have to dig to fix the root problem, not its consequences.

Domain experts usually come to us with solution. The trick is to respectfully challenge them and their solutions. Be a learner, do your best to understand their work and what problem they are trying to solve.

The coffee machine is definitely the place to be to learn things in an informal way.

I often use the 5 whys, and graphical representation to crunch knowledge. Drawing is a fantastical tool to understand complex problems. If you can’t draw it, you can’t understand it. I also organize more formal exchange like Event Storming or Impact Mapping depending on the context.

Whenever it’s possible, I spend some time with the actual users of a system. Usually it’s where we learn the most, seeing how wrong our assumptions were.5WhysAlign the technical implementation with the domain

Have you ever try to show your code to a domain expert ? You should. Our code tells a story, it must be understandable by domain experts. The next developer should learn about our domain, just looking at our code.

It’s where we need an Ubiquitous Language, and a clear separation between domain and infrastructure concerns. The Onion Architecture allows that, but it’s not the only way.

Another great way to align our implementation with our domain is Living Documentation. This topic would deserve a whole blog post (or you can read Cyrille’s book). I would just say that it is not only BDD. Living Documentation is more like : how do you generate documentation from your code, not how do you write code from documentation.

Concrete example are the generation of:
– Change log from commits (using GIT)
– API documentation understandable by domain expert (using Sandcastle)
– Workflow description (using static code analysis and tags)

It’s amazing to see the direct impact of these techniques on your codebase. To generate useful stuff from your code, it needs to be clean, and aligned with your domain, in terms of naming and meaning. If the quality is poor, you won’t be able to generate anything understandable. If code and domain are not aligned, you will receive complaints from the domain experts, about how classes/namespaces/modules are badly named. How awesome is that ?AlignKeep our implementation easy to modify

The business may (will) change, how do we hope to stay aligned if we resist changes? It gets on my nerves when I hear a developer complains because business people “do not know what they want”. Of course they don’t, they can’t forecast the future. Our job is precisely to provide great software, even when requirements and constraints change a lot. I would even argue it’s one of the main difference between high quality software versus cheap software. Good software is resilient to change, bad software is a pain for its developers and users whenever something new happened. What is the point of being “Soft” if we are unable to change?

Our industry knows how to develop software easy to change. We use Unit Testing to provide quick feedback when anything changes in the system. A SOLID design will keep low coupling, which help to change part of the system without breaking everything.

To have a more complete feedback loop, we use DevOps to achieve continuous integration and continuous deployment.solid-principles-e1428402535364DDD is a lot of good habits

We can’t implement DDD without problem analysis, technical alignment with the domain and a codebase easy to modify. I tried to show that DDD is not something hard. I’m sure you already do, or at least heard about some of the practices I talked about in this post. You don’t need to learn all at once. Be a constant learner, one practice after the other.

Learn about these practices, try to implement them, and you also will get a lot from DDD, in your daily work.

 

 

Many thanks to my usual reviewer Brian Gibson.

 

Clarifying MVVM with DDD

I regularly see a lot of questions around MVVM, last one only a few weeks ago.

The problem is usually the same: what should be a Model, and what should be a ViewModel?
We can’t really blame developers, because references online are not really good, especially MSDN’s one. The explanation is simplified to be understandable for most developers. The result is an oversimplified pattern which doesn’t fit for complex line of business application.

There are many contradictory implementations of MVVM. I’ll describe in this post an effective implementation for me since many years.

Contradiction

Problem roots 

Everybody agree on a ViewModel definition: it is an abstraction of a View. This abstraction is simpler to test than the GUI, we don’t need to run the solution to test a ViewModel in isolation. It decouples UI design from UI behavior.

But what should be in this ViewModel abstraction is really unclear. Usually the implementation is a ViewModel where we put too much business logic, and a simple POCOs Models (mainly because of ORMs). In this case, a question arises: when I use only one Model in one ViewModel, do I need a ViewModel at all ? Can’t I just bind the model and notify the View if one of the properties is updated ?MVVM1

 DDD to the rescue

Domain Model is a tactical pattern from Domain Driven Design (DDD), which could fit the Model in MVVM. Using DDD, we want to avoid Anemic Domain Model, which clarifies what could be a MVVM implementation.

The ViewModel is only an abstraction of the View, and it manipulates Models where the business logic is.

For example a ViewModel can use a User to change an address:

user.ChangeAdress(new Adress("3 route de tartampion", "6900", "Lyon", "France"));

MVVM2What if I need several Models?

Another tactical pattern from DDD could help us: Domain Service. A Domain Service is where we manage interaction between Domain Models. We use it if we do not find a better place to put the business logic for a given use case. Our ViewModel will manipulate Domain Services, which manipulate Domain Models. Typical use case requiring several Models is validation.

For example a ViewModel can use a buying service to validate a command:

_buyingService.Validate(/*products to buy*/, /*current user*/)

MVVM3

What if I don’t know/care about DDD?

Just replace the word DomainModel by Model, and DomainService by BusinessService. Apply SRP to well design classes.

For example in C#, a Model should not be INotifyPropertyChanged, it is a UI concern. It’s the responsibility of a ViewModel to notify a View when a property changed.

In the same idea, a ViewModel should not embed business logic, since it is already responsible for UI behavior. MVVM4Simple rules for simple design 

  • A View has the responsibility to display something to our user. We don’t want any behavior here.
  • A ViewModel has the responsibility to represent the behavior of our View. We talk about UI behavior, not Business behavior.
  • A Model has the responsibility to encapsulate the business logic, and do not care about how it will be display. It’s where we put business behavior.
  • A Business Service has the responsibility to encapsulate the business logic for a given use case, if several Models are involved to meet a business needs.

MVVM6

I tried to give a simple example on Github. (Note that I let the DDD part away).
Any feedback welcome.

 

Thank you Brian Gibson for the suggestion to add diagrams.

 

Panorama to Hub

If you decided to use a Panorama control in your Windows Phone application, then you will be as disappointed as I am to discover Microsoft remove it from the Universal Windows Platform.

With a quick search on the web, you see it should be easy to replace with a Hub control.

But, surprise, the convenient ItemsSource property has been removed. In a panorama it was easy to bind a data source to generate one panorama section per item. You can’t natively do that with a Hub.windows-phone-7-panoramaDear Microsoft, bringing some cool stuff from Linux is great, but please consider keeping convenience for what is already awesome in your development environment: DataBinding. I would even say it’s one of the killer feature of C#/XAML applications.

Anyway, I will describe a DynamicHub implementation, to get the ability to generate one hub section per item in your data source.

First re-create your own DependencyObject. Then when the interesting dependency changes, iterate on your data and create one hub section per item.

    public class DynamicHub : DependencyObject
    {
        public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.RegisterAttached(
            "HeaderTemplate",
            typeof(DataTemplate),
            typeof(DynamicHub), new PropertyMetadata(null, HeaderTemplateChanged)
            );

        private static void HeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var hub = d as Hub;
            if (hub == null) return;
            var template = e.NewValue as DataTemplate;
            if (template == null) return;
            foreach (var hubSection in hub.Sections)
            {
                hubSection.HeaderTemplate = template;
            }
        }
        public static void SetHeaderTemplate(UIElement element, DataTemplate value)
        {
            element.SetValue(HeaderTemplateProperty, value);
        }

        public static DataTemplate GetHeaderTemplate(UIElement element)
        {
            return element.GetValue(HeaderTemplateProperty) as DataTemplate;
        }

        public static readonly DependencyProperty SectionTemplateProperty = DependencyProperty.RegisterAttached(
            "SectionTemplate",
            typeof(DataTemplate),
            typeof(DynamicHub), new PropertyMetadata(null, SectionTemplateChanged)
            );

        private static void SectionTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var hub = d as Hub;
            if (hub == null) return;
            var template = e.NewValue as DataTemplate;
            if (template == null) return;
            foreach (var hubSection in hub.Sections)
            {
                hubSection.ContentTemplate = template;
            }
        }
        public static void SetSectionTemplate(UIElement element, DataTemplate value)
        {
            element.SetValue(SectionTemplateProperty, value);
        }

        public static DataTemplate GetSectionTemplate(UIElement element)
        {
            return element.GetValue(SectionTemplateProperty) as DataTemplate;
        }

        public static readonly DependencyProperty DataSourceProperty = DependencyProperty.RegisterAttached(
            "DataSource",
            typeof(object),
            typeof(DynamicHub),
            new PropertyMetadata(null, DataSourceChanged)
            );

        private static void DataSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var data = e.NewValue as IEnumerable;
            var hub = d as Hub;
            var template = GetSectionTemplate(hub);
            var header = GetHeaderTemplate(hub);
            if (data == null || hub == null) return;

            hub.Sections.Clear();
            foreach (var section in data)
            {
                var sect = new HubSection { DataContext = section, ContentTemplate = template, HeaderTemplate = header };
                var hubData = section as IHubData;
                if (hubData != null)
                {
                    sect.Header = hubData.Header;
                }

                hub.Sections.Add(sect);
            }
        }

        public static void SetDataSource(UIElement element, object value)
        {
            element.SetValue(DataSourceProperty, value);
        }

        public static object GetDataSource(UIElement element)
        {
            return element.GetValue(DataSourceProperty);
        }
        private interface IHubData
        {
            object Header { get; }
        }
    }

Here is a XAML example to use it:

        <Hub local:DynamicHub.DataSource="{Binding HubSections}"
                local:DynamicHub.SectionTemplate="{StaticResource HubSectionTemplate}"
                local:DynamicHub.HeaderTemplate="{StaticResource HubHeaderTemplate}">
        </Hub>

And a data template to display it:

            <DataTemplate x:Key="HubHeaderTemplate">
                <StackPanel>
                    <TextBlock Text="HubHeader" Style="{StaticResource TitleTextBlockStyle}"/>
                    <TextBlock Text="{Binding SectionHeader}" Style="{StaticResource TitleTextBlockStyle}"/>
                </StackPanel>
            </DataTemplate>
            <DataTemplate x:Key="HubSectionTemplate">
                <StackPanel>
                    <TextBlock Text="HubSection" Style="{StaticResource BodyTextBlockStyle}"/>
                    <TextBlock Text="{Binding SectionNumber}" Style="{StaticResource BodyTextBlockStyle}"/>
                </StackPanel>
            </DataTemplate>

Hope it helps, full demo code is on GitHub.

 
IP Blocking Protection is enabled by IP Address Blocker from LionScripts.com.