Skip to main content

Posts

Showing posts from April, 2015

Getters and Setters are Evil - Redux

Back in early 2011 I wrote one of my most viewed and commented posts at the time - Getters and Setters are Evil. Four years later it's time to review this.The feedback within the team was generally positive. Production code was written in this style to great success. The core benefit was encapsulation was preserved as Business Objects were the sole source of domain logic. As an additional side effect testing was easier.However not everyone within the team agreed that the benefits were worth the extra hassle or believed in the benefits of encapsulation. I always found the addition of an IRender interface or similar broke the SRP, even if you moved the logic to a separate class. The OCP suffered too, if view requirements changed, you need dig out your business object. The biggest failing is that legacy code and frameworks still require public getters/setters to function.Overtime I found myself and others slipping back to the "old ways" of applying getters/setters without t…

CQRS - The Simplest Introduction

CQRS or Command Query Responsibility Separation is easy to understand but it can become complex due to various levels to which developers take the principle behind it. Simply - CQRS is two models, where the used to be one. Nothing more at its heart.Take the Customer aggregate below. This exposes both commands as void methods and queries as methods with return types. Public state is leaked, but needed in order to display or persist the data. Many frameworks or libraries require public accessibility in order to function.CQRS states we split commands from queries. This means we end up with a pure Customer aggregate root that exposes behaviour only. Likewise we end up with a basic application service that simply returns data.BenefitsCommandsDomain model is purely behaviour.No data is exposed, public fields/methods gone (no getters/setters)Only way to modify customers is via the commands - encapsulation is preserved.Less relationships simply for querying/persistence (has-a relationships)Te…

Cool URI's Don't Change

I switched domains back in June 2013. This was out of my control. A lot of links were lost despite an attempt to backlink in order to keep the traffic from the old links and new links crossing over. The previous domain also broke content without consideration, there are links around that simply point to nothing.To compound the issue I switched this blogs platform back in June 2014. This was much overdue, but an issue fully in my control. This yet again, broke links despite being for the better. My link management has been poor and given how annoyed I become at other sites breaking links, it's time to make a stand.A recent example was when I was on holiday with a limited wifi connection of an evening. A couple of users on Twitter wanted to share some of my content, but the link was broken. After some delay and flip flopping I was finally able to share the post they were after. I am extremely happy that Paul thought of a blog post I wrote, so the fact that he was unable to share it …

DRY vs DAMP in Tests

In the previous post I mentioned that duplication in tests is not always bad. Sometimes duplication becomes a problem. Tests can become large or virtually identically excluding a few lines. Changes to these tests can take a while and increase the maintenance overhead. At this point, DRY violations need to be resolved.SolutionsTest HelpersA common solution is to extract common functionality into setup methods or other helper utilities. While this will remove and reduce duplication this can make tests a bit harder to read as the test is now split amongst unrelated components. There is a limit to how useful such extractions can help as each test may need to do something slightly differently.DAMP - Descriptive and Meaningful PhrasesDescriptive and Meaningful Phrases is the alter ego of DRY. DAMP tests often use the builder pattern to construct the System Under Test. This allows calls to be chained in a fluent API style, similar to the Page Object Pattern. Internally the implementation wil…

Randomly Generated Values in Tests

The use of randomly generated test data seems like a good thing at first glance. Having worked with several teams that have used this concept I generally discourage the practice. Consider a simple method that joins together two strings. A test using random values may look like this.ProblemsHarder to ReadWhile this is a toy example to demonstrate the problem, in more realistic scenarios the lack of literal values harms the readability of the tests. It is worth noting the lack of literals causes more lines of code as anything that has importance needs to be stored in a variable or field. My biggest concern is when assertions start to become complicated or even worse, duplicate production code in order to pass. If we wish to treat tests as examples, this is pretty poor.Edge CasesGenerating a random string seems easy enough. Overtime the edge cases in question start to ramp up. You have whitespace, special characters, new lines, numbers and much more to worry about if you wish to do this …