Mark van Venrooij

Mark van Venrooij's blog

Tag: Craftsmanship (page 1 of 4)

Applying Domain-Driven Design

tl;dr

In this post I apply Domain-Driven Design to my favorite pet project. The picture above contains the resulting model. The resulting code can be found at GitHub.

My attempt on Domain-Driven design

As mentioned in my previous post I need to learn Domain-Driven Design for my new job. In this post I apply the things I learned till now to an application that gives me insight in my financial situation. The domain is very familiar to me as I used it before to learn new things. The application mainly tells me where I spent my money. Next to that I set yearly budgets on each category in the beginning of a year. During that year I will compare the budget against the actual situation to assess if I’m still on track. Ideally the application also incorporates some functionality to calculate my savings rate and some other metrics related to reaching financial independence.

Ubiquitous language

Eric Evans’ book emphasizes the importance of the ubiquitous language. So let me try to define the ubiquitous language for this application.

To achieve financial insight the application needs to import and categorize financial transactions. I want to set budgets for a year and compare them to the actual amounts. Furthermore based on the actual numbers the savings rate and years till financial independence must be calculated. In order to calculate the years till financial independence there is something to assess my savings and investments.

The bold words seem fundamental concepts to me. These words should play a major role in my domain. Probably I miss a couple of concepts right now, but that is fine. I will refine the ubiquitous language later. The most interesting part of the application to me is the last part: calculating the metrics on FI. However these are a result. In order to achieve FI earlier there are two possibilities:

  • Increase your income
  • Reduce your spendings

The application will not help in getting more income. Getting insight in your expenses can help to see when budgets are exceeded and where expenses are high. So for now I first focus on categorizing financial transactions and creating budgets.

Please note that for my personal finances I don’t use double bookkeeping as it seems overkill. Next to that I ignore any cash transactions. Not categorizing cash transactions will not influence my insights much as I don’t use a lot of cash. Next to that keeping all receipts is too much of a burden to me.

Entities versus value objects

After defining the ubiquitous language the next step in Domain-Driven Design is to try to make the model. Important parts of the model are the entities and value objects. As the focus is on categorizing and budgeting I find at least 3 objects of interest: Category, Transaction and Budget. To me a Category is an entity. Mainly because in time the amount of money spent in a Category will change via adding new transactions. Furthermore there must be a Budget more specifically a Budget per Category per year. Budgets are entities as pretty much anything can change in time.

If I look at Transaction I’m a bit in doubt. During the life cycle of my financial administration a transaction will not change. That is because they are originating in an external source: my bank. Next to that I’m only concerned about the values of a Transaction. If I need to make a guess I think I need an account number, a contra account, the date, the amount and the description of the Transaction. These fields are also the important ones in my naive Bayesian classifier to categorize my transactions. For now I make a choice to make a Transaction a value object. This might be revisited later.

Identities & associations

For Category the name is a good identity. There is a unidirectional association from category to zero or more Transactions. Next to that there is a unidirectional association between a Budget and a Category. Because setting a Budget without being able to categorize real Transactions doesn’t make sense, it is not possible to have a Budget without a corresponding Category. Over the years there are many Budgets per Category, however per year there can be only 1. This means that for the identity of the Budget it is probably wise to include the year. To me combining the Category and a year seems a good choice as identity for the Budget.

Aggregates

Time to define some aggregates in the model. Typically a Budget is created at the beginning of each year and Categories are created once (and maybe adjusted once in a while). However during the year I import and categorize my Transactions. For me this leads to a logical split. Making Budget an aggregate with only one entity. Category and Transactions are an aggregate as well. Category is the aggregate root. As Budget is a separate aggregate root I don’t want to include the Category as an object. I just want to have a reference to a Category through its identity. This has implications for the Budget and its identity. It identity is now made of a Category name and a year.

Repositories

Time to choose the repositories. My first attempt is a repository per aggregate. Given the requirements this makes sense to me now. In the future I probably want to persist my data somehow. Maybe with a relational database, maybe an object database or maybe just plain old CSV files. For exploring and building the domain this is not relevant. Furthermore maybe some future feature(s) will give me more information what storage technology will suit my needs. For now I will just use an plain old java implementation of my repository, using the collection classes.

Creation of aggregates

Creating a category is straight forward as there are no special requirements here. So a constructor will suffice. However for creating a Budget we need to make sure that there actually is a Category available. To check if a Category exists I need to find the Category by name using the CategoryRepository. I could make an association in Budget to that repository. However that seems bad practice. I think creating a BudgetFactory makes sense in this case.

Conclusion

Given the small number of objects in the domain now I don’t find it necessary to split these classes among different modules yet. The model created seems to cover my basic needs of storing the budgets and categorize transactions. The complete design is shown below.

The resulting DDD model

The resulting DDD model

Next to that the resulting code, including unit tests, can be found on GitHub. However I didn’t implement comparing budgets to actual expenditures yet. Next to that I only implemented the model so at this moment there is no application to run. These are topics for another blog post.

Learning domain-driven design

On my new job the department is applying Domain-Driven Design. I did read Domain-Driven Design – Tackling Complexity in the Heart of Software by Eric Evans a couple of years back. However as I never used it I need to learn how to apply it. So in order to really learn DDD I started to reread Eric Evans’ book and plan on reading Implementing Domain-Driven Design by Vaughn Vernon. As theory and practice are only equal in theory, I want to apply DDD to my favorite pet project. To recap an earlier blog post, many years ago I started categorizing all my financial transactions. At first I used to build a tool myself to give me insight in my spendings, later I bought something to do this for me. However this is now the domain I know pretty well and use to learn new things.

Current progress

Currently I read till chapter 5 of Eric Evans’ book. The key things I learned in the first chapters:

  • Make domain concepts explicit by capturing the knowledge in the design
  • Define a ubiquitous language using domain terms
  • The feedback loop from coding back to the design is often missing
  • The domain must be isolated from the user interface, db glue and other supporting code in order to achieve separation of concerns
  • The smart UI cannot be combined with DDD

Moving forward

My plan is to finish reading both books before the end of the year. (I hope I can find the time, given that I have a young daugther.) In the same time I plan to work on my pet project. As I learned long ago a good way to learn things is to teach others. So I want to share my progress in implementing DDD on my pet project through this blog. So the coming weeks expect some new blog posts on this topic. Basically me struggling to apply the DDD concepts.

Review: The clean coder

Cover of the clean coder

The clean coder

Last week I finished reading The clean coder written by @unclebobmartin. The book’s subtitle: “A Code of Conduct for Professional Programmers”, summarizes the book quite good.

Throughout the book @unclebobmartin tells about his own experiences during his career. Also he illustrates the points he wants to make with excellent example discussions between (project) managers and developers. These example stories are quite entertaining and make the book easy to read.

The first few chapters discuss how a professional developer behaves as a person. It’s all about managing expectations & making sure that you’re in the right state to do your job. After that some practices that improve the quality of your work are introduced. Examples practices are TDD, testing in general and estimation. The last chapters discuss how to behave in a team. A embarrassing paragraph in these chapters is called “Degrees of failure”. In that part @unclebobmartin basically explains how the education system fails to educate software developers.

It’s a nice book to read and has nice suggestions how software developers can improve their work and become craftsmen. However many of these tips are not new to me. They can be found in the enormous blob of blogs about agile / lean / etc. development. Only the estimation chapter gave me some real new information. Because the book is written in @unclebobmartin’s distinctive style I still recommend the book. The pragmatic programmer is a different league though.

How I learned about customer value

Confidence by h.koppdelaney, on Flickr

Confidence by h.koppdelaney, on Flickr

The article do users change their settings remembered me about a program I wrote as a student. I created a tool to categorize my expenses similar like Yunoo a.k.a. Afas Personal. This was however a local application. Why the heck should you share your finances on the internet? But let me go back to my memory. At the time I started building the application I did a little bit of research if there was this kind of software available. Sure there was, I just thought it didn’t look nice so I build it myself using Swing (I do know better now ;-)). I was just a little bit overconfident and suffered from the NIH syndrome.

Basically the application enabled me to download a file with all my transactions, load it to my program and categorize my expenses. I even created some rule engine like thing to categorize recurring transactions automatically. All these transaction are then shown in a JTable structure. The program also included budgeting, reports, some graphs, etc.

Back then I didn’t like how the information was shown in the transaction overview. There was too much information shown and it was shown in the same order as was used by the import file. So I made this table structure configurable. The configuration made it possible to hide columns and rearrange them. Also I created some ways to edit the configuration and store it into an XML file (it was the common fashion back then). This change resulted in al lot of work. I needed to create file handling & XML parsing code. But the main issue was that I used the UI as the (view) model.

Every transaction had an id which was shown in a column. It was quite easy to create the logic to find the transactions id as long as the id column was shown. If it wasn’t shown however it was not possible to match a row in the table to any transaction stored in the database. This was especially difficult because every other column may or may not be visible. So I created a view model that made is possible to find the transaction corresponding to the data shown in the UI. Because I wasn’t used to writing automated test (as everyone knows a real programmer doesn’t test), it took quite a while to create the model, hook it up to the interface and make it configurable. I think I spent at least some 40-60 hours on this feature. When I was done I was pretty proud as a developer that I was able to create this feature.

As the only customer of the product I wasn’t happy though. Yes the new feature improved my application a bit. But it didn’t help to support the main goal of the application: getting more insight in my expenses. The day I realized this I was pretty disappointed. If I look back now I learned a lot about customer value by making this (classic) mistake. This is also why I keep emphasizing customer value in the Agile/Scrum team I’m part of. By the way I learned a lot more by building this toy project. I still have all the sources of the program & I use it from time to time to experiment with new languages (I have some Scala classes that mimic the original functionality in Java), new practices and new IDE’s. As a software developer I think every other developer should have toy projects to experiment and improve his/her skills and become a craftsman.

Now I’m using an off-the-shelf product to categorize my expenses and make budgets. Sometimes I still have that nagging feeling that I could make a better program than the one I bought. I learned however that if I’m going to build this thing I need to spend a lot of time to have the same capabilities I like in that product and I think I can spend my precious time more effective.

Developer certificates are similar to triple A ratings

 

Coin Operated by xcode, on Flickr

Maybe it is a far-fetched comparison but to me developer certificates (e.g. the Sun Java Certified Programmer) are quite similar to the triple A ratings issued by companies like S&P. Let me try to explain why I think they are similar.

Basically a rating or certification agency does some quality checks for you. Banks are outsourcing the risk assessment of certain financial products to the rating agencies. I think banks should always check the risks of the product they are buying themselves. Software companies use the developer certificates to outsource the quality checking of a (potential) new employee. And if I was the person who was hiring people I wouldn’t even think about outsourcing this pre-employment check.

By outsourcing these checks we explicitly trust trust the companies providing the service. Initially this makes sense, especially when you are an HR person who doesn’t know the details about the job a potential employee has to do. The problem however is that the certification agency benefits most if they check as many people as possible with the least possible effort. Also a developer pays for his certification resulting in the situation that the developer is the main customer of the certificate authority. I don’t think we should trust the agencies blindly. This is of course similar to the situation of the rating agencies (like discussed after the USA downgrade by S&P).

So are certificates useful? I agree with Martin Fowler’s article: CertificationCompetenceCorrelation. Bottom line: He hasn’t found a correlation between certification and competence, but it may have a economic value for the developer.

 

Older posts

© 2018 Mark van Venrooij

Theme by Anders NorenUp ↑