Saw a talk of mine from Oredev went online. 19 1/2 things to make you a better OO programmer
19 1/2 Things to Make You a Better Object Oriented Programmer - Greg Young from Øredev on Vimeo.
So just what the hell is grensesnitt anyways?
Let’s start with the name. Grensesnitt means interface in Norwegian. The direct translation however would be “boundary cut” which is exactly what grensesnitt does. Grensesnitt is an nunit plugin I wrote a while ago while in Norway. It allows me to write tests in a style that I have been writing them in for a few years now while removing the pain of doing so. You can grab grensesnitt on mygithub , to install just copy it into the addins folder of your particular nunit installation. If you want to just test it out, its installed in the nunit installation included in the /lib folder (you can run the tests in the sample project).
Many of our tests should not be written against classes but should instead be written against interfaces. They represent the invariants of the given interface. Consider as an example IList, I don’t care how you implement IList but if I call add and you return to me without an error, count needs to increment and I need to be able to get the item back. If you cannot do this in my eyes you are not really an IList as I cannot use you. Seriously, can you imagine someone passing you an IList that when you added stuff to it, you couldn’t get it back out? Right now we tend to have all of these assumptions implicitly, grensesnitt allows you to make them explicit.
nunit allows you to do some things like this using Generic Test Fixtures such as
[TestFixture(typeof(ArrayList))]
[TestFixture(typeof(List<int>))]
public class IList_Tests<TList> where TList : IList, new()
but there are some drawbacks to this. First I need to actually add the type to the test manually, what if I forget? manual steps suck. The second is that the test assembly needs references to all of the implementers which can be problematic.
With grensesnitt:
public interface ICanAdd {
int Add(int i, int j);
}
[InterfaceSpecification]
public class ICanAddTests : AppliesTo<ICanAdd>{
[Test]
public void can_add_two_numbers() {
Assert.AreEqual(5, sut.Add(2,3));
}
}
This would be the code that you would write. Grensesnitt will then automatically find any class that implements ICanAdd and these tests will be run against it. This automation of the process is very important. Said simply as soon as you implement ICanAdd you have N failing tests. Grensesnitt is capable of running either explicit interfaces or class interfaces (i.e. inheritance)
When you run grensesnitt, it will automatically find these implementers and you will see your tests show up as a test suite per implementer. As you can see in the image below. Adder1, Adder2, Adder3 etc are all implementers of the adder interface.
You can also control where grensenitt searches for implementers by using the [assembly: GrensesnittSearchLocation("../plugins")] attribute on your test assembly. By default it will search in all the assemblies in the directory.
Grensesnitt also plays nice with other nUnit plugins. As an example here is a test (shown above in runner) that also uses TestCase for parameterized tests.
[InterfaceSpecification]
public class WithOtherPlugins : AppliesToAll<ICanAdd>
{
[TestCase(1, 2, 3)]
[TestCase(-1, 2, 1)]
[TestCase(0, 0, 0)]
public void CanAddOrSomething(int x, int y, int r)
{
Assert.AreEqual(subject.Add(x, y), r);
}
[TestCase(1, 2, Result = 3)]
[TestCase(-1, 2, Result = 1)]
[TestCase(0, 0, Result = 0)]
public int CannAddOrSomethingWithReturn(int x, int y) {
return subject.Add(x, y);
}
}
Now ask yourself, how many times have you implemented an interface out of some library, then passed your implementer in and gotten some really weird bug happening 65 levels down the call stack in their code? Its because of something in your implementer but you don’t know what? Grensesnitt is a way to allow a framework developer to document their needs. They release the grensesnitt tests with their code. When you implement their interface, their context specifications get run automatically against you (it’s a form of documentation), and it works very very well with BDD style tests.
Grensesnitt is also fairly opinionated and its hard to do bad things. Grensesnitt does not as an example require default constructors on objects. Instead there is a hookable object creator. GrensesnittObjectLocator that you can hook all or specific calls to a factory method. Its like this by design, if your test depends on something being passed to a constructor eg: if I pass 5 to the constructor this property should return 5 that is *not* an interface test, it is a class test.
Anyways it makes this testing style easier for me so maybe it will benefit others.
Special thanks to Svein, Morten, and Einar who all helped with the creation of grensesnitt. Oh and nevermind all the dead bodies in the plugin itself (copy/pasted private code from nunit with internal calls replaced with reflections) those were just casualties from fighting the dragons that be in nUnit.
Just put up http://cqrsinfo.com as many people have been asking for the information.
You will find there documents, 6-7 hours of video, and links to good material on the web.
What is CQRS? Well if we ask google it will say "did you mean CARS?" (although it seems for developers who search a lot it now actually comes up.
According to http://www.all-acronyms.com/CQRS CQRS is Commercial Quality Rimmed Steel
CQRS is none of these things. CQRS is not new. One of my favorite questions I get from people is "How many real systems are there running with this kind of CQRS stuff". The answer is ten if not hundreds of thousands. It even funnier when asked about Event Sourcing as I actually worked on a system 10 years ago using Event Sourcing (it used to be really popular).
CQRS is pretty much MVC!
I have had very few people notice this when teaching but occasionally a bright one will pick up on it. Of course CQRS is not precisely MVC but it is definitely a variant. Let's go way back to 1979 and look at what Trygve had to say about MVC. http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf
MODELS
Models represent knowledge. A model could be a single object (rather uninteresting), or it
could be some structure of objects. The proposed implementation supports knowledge
represented in something resembling semantic nets (If I understand Laura correctly)
There should be a one-to-one correspondence between the model and its parts on the one
hand, and the represented world as perceived by the owner of the model on the other hand.
The nodes of a model should therefore represent an identifiable part of the problem.
The nodes of a model should all be on the same problem level, it is confusing and considered
bad form to mix problem-oriented nodes (e.g. calendar appointments) with implementation
details (e.g. paragraphs).
VIEWS
A view is a (visual) representation of its model. It would ordinarily highlight certain attributes
of the model and suppress others. It is thus acting as a presentation filter.
A view is attached to its model (or model part) and gets the data necessary for the presentation
from the model by asking questions. It may also update the model by sending appropriate
messages. All these questions and messages have to be in the terminology of the model, the
view will therefore have to know the semantics of the attributes of the model it represents. (It
may, for example, ask for the model's identifier and expect an instance of Text, it may not
assume that the model is of class Text.)
The main difference when we talk about a system that has had CQRS applied is that there are TWO models. There is a model representing the mental model of the user and there is another model representing how transactions flow through the system. These two models are often eventually consistent with each other. The model on the read side, supporting the views is read only. The model supporting the controllers is write-only. Synchronization is achieved either through a shared data model or through events from the write model to the read model.CQRS is pretty much MVC. I am not sure I would assert that it is MVC given the definition but it is very similar. I also doubt that it is Udi or I who first thought of doing it. My guess is you can find many systems doing it.
CQRS is also very similar to P-7: INPUT/OUTPUT SEPARATION in http://heim.ifi.uio.no/~trygver/2003/javazone-jaoo/MVC_pattern.pdf
The input and output aspects of the Editor are technically very different with few interdependencies. Their
combination in a single object tends to make this object unnecessarily complex.The major difference being the separation is only being applied at the first level then returning to a single model as drawn (CQRS is about driving this separation further and further back with benefits at each step). I am rather certain that Trygve has also come across the point that very often the model representing the user's mental model is often very different than the model for expressing how invariants are maintained and that it can be advantageous to push the separation even further back to the models. The benefit is also seen technically when pushing even further back to data storage mechanisms.
Understanding this will take you a long way towards understanding what people are talking about with CQRS it is certainly a variant of if not actually MVC.
If you are from Australia they are trying to get me to come down. Could you fill out this?
Under 500 lines of code before the client
http://github.com/gregoryyoung/m-r
I will write a blog post about some of the stuff in it but its pretty straight forward.
I was going to do the last class on a Saturday in GMT http://dddcqrs3.eventbrite.com but a bunch of North Americaners were saying they would like a weekend version as well in their timezones. As such I put up one for Saturday that people can register for http://usacqrsddd.eventbrite.com/
The material is the same as previously just in a weekend time format.
Material covered includes:
The format of this is meant to be open to the community. As such the only form of payment is donations.
This post comes from a discussion I had with Clemens Vasters at NDC but is a much bigger discussion than the context we had it in which was Azure specific. An exaple of where this also comes into play is with the REST crowd who also want all idempotent operations.
Sure distributed transactions are evil ... until well they aren't. There is a trade off between capital investment and *insert whatever reason you don't like distributed transactions*. First let's look at the alternative.
To briefly cover idempotency from Gregor
"In the world of distributed systems, idempotency translates to the fact that an operation can be invoked repeatedly without changing the result."
This is a huge benefit because in failure conditions etc, I can just send you the same message multiple times and it won't affect you in a bad way. As an example I peek a queue and process the message writing something. Then suddenly my power goes out before I have actually removed the item off the queue. When I start up, I can just re-process the message (it won't cause destructive change).
Many operations are idempotent to start with. Consider a read or the setting of a property. Other options are not idempotent and need code to be written to make them idempotent as an example charging someone's credit card what happens if you get that message twice, ouch. The trick here is the operations that are not naturally idempotent, they require us to write code to make them idempotent. That code has a cost associated with it in terms of creation, maintenance, testing, and conceptually.
Clemens gave an example of a system he worked on to illustrate his point, a credit card processing system.
A credit card processing system has a very limited number of possible transaction types. For sake of discussion let's say that there are 15 and they are called very often, each has a large amount of logic associated with each transaction type (a similar example might be a trading system, not a lot of command types but a lot of logic associated with each). In these cases the idempotency is not a big deal because the amount of code being added is very small for it as a percentage of the total code.
This is very different than a stereotypical business application where there will orders of magnitude more transaction types and they will be often called rarely with small amounts of logic behind them ... for sake of discussion let's say closer to 1500 types with the detection code being vastly larger as a percentage (I have seen business systems where there was more code to ensure the idempotency than to perform the actual operation).
We can make everything idempotent but we will have a very different cost associated with it in the stereotypical business system than with the first system. Out of our 1500 operations how many of them are not naturally idempotent? How much code will we have to write in order to make them idempotent (quite likely ALOT!). Looked at as a percentage of the overall code it will be much higher than in the first example as there is much less code per transaction type on average.
Now what are we gaining by this overhead in order to have all idempotent operations? Scalability and Availability are two things that come immediately to mind. It is very hard to scale distributed transactions to an extremely high level (think Azure scale), many other trade offs start to come in at this level of scaling.
Are you scaling to Azure level? What is the ROI of that code you wrote to make things idempotent for the business system? This is not to say to use distributed transactions haphazardly (you always want to limit their usage as much as possible) but to point out that there are certainly situations where they may be favorable, there is a tradeoff involved. Again this is not to pick on Azure alone, REST also does this.
It is important to consider this tradeoff when you decide to say put an application onto Azure. How well do their non-functional requirements as a platform meet yours as an application? What types of decisions like this have they forced upon you and what will be the long term cost of those decisions.
I was just writing an email to the cqrs group http://groups.google.com/group/dddcqrs and figured it might be useful to put it up here as well as its a very common question I get.
The initial question was
Here's the example I'm using:
A system that handles user registration for 2 million+ active users. These users should be able to login with their email address and password. They should also be able to change their associated email.
I have the following design:
Entities:
User(Guid Id, string email, string hashedPassword)
Events:
UserRegistered(Guid Id, string email, string hashedPassword)
UserEmailAddressUpdated(Guid Id, string email)
Commands:
RegisterUser(Guid Id, string email, string hashedPassword)
UpdateEmailAddressForUser(Guid Id, string email)
ViewCaches:
RegisteredEmailAddresses(emailAddress) - Used for client side validation on email prior to sending a RegisterUser command
When processing a RegisterUser command, I need to validate that no other user has registered with that email. How can I do that without loading every user in the system? I could use a view cache like the client side, but then I would have business logic outside of my domain. Any suggestions?
This is a very common question. There were many responses with various suggestions. Mine follows.
I am just replying to the last one on the list after reading through.
To me the most important concepts have been completely missed in this
thread and they are a big part of why eventual consistency is so cool
(it makes you think about things).
*What is the business impact of having a failure*
This is the key question we need to ask and it will drive our solution
in how to handle this issue as we have many choices of varying degrees
of difficulty.
Most of the time the business impact of such a failure is low and the
probability of it happening is low. If we query the eventually
consistent store at the time of submission (either from client or from
server as this is a big part of how one-way commands work) then our
probability of receiving a duplication is directly calculable based on
the amount of eventual consistency. We can drive this probability down
by lowering our SLA very often this is enough.
We can detect asynchronously if we broke our invariant. Imagine an
eventhandler that inserts into a table with a constraint. If it gets
an exception, we broke the constraint (note this is not really the
"read model" but the same db can be used if convenient, it is
important to note the distinction as if we scale to have 5 read models
we don't have 5 of these ...).
What do we do if we break the constraint? We need to come back to that
business impact statement above. For most circumstances, just raising
an alert to an admin etc is enough, these things are very low
probability of happening and are often not worth the time/cost of
implementing automatic recovery. Just imagine 1 username create out of
1,000,000 fails this way. How long would it take to automate the
process of handling the situation? Consider discussions with domain
experts etc. 5 minutes of admin time once a year is much better ROI in
most of these situations than a week of developer time to automate.
Continuing along it has now been decided that this has large enough
impact that it should be automated. The said process that finds the
duplicates could either raise an event DuplicateUsernameDetected or
directly call a command ResolveDuplicateUsername (which involves more
discussion). It is important to note that in either of these cases we
are discussing the "What" not the "How" it would never issue a command
"DeleteUser" etc, how to handle these situations is core domain logic
and should be modeled within the domain. In the username example
perhaps ResolveDuplicateUsername marks the user as not being able to
login (and as a duplicate) and it sends an email to the user saying
"Hey we screwed up but its your lucky day! you get to create a new
username ..."
But even after all of this if from a business perspective the impact
is too high we can still make things consistent. We could drop in a
service to the domain that deals with a consistent set. This would of
course be the last resort as its the most complicated of these
solutions and brings with it many limiting factors in terms of our
architecture.
Udi had a great example of this in his explanation of 1-way commands.
It was an ATM that would spit out money having only read your balance
from an eventually consistent read model. The reason this can work is
that from a business perspective the risk is low (and it is built into
the business model itself). You have a bank account with me, I know
your SS# and all of your information. For people who overdraw their
accounts I will recover atleast 90% of the money that has been
overdrawn. On top of that I charge a fee for each overdraw that
occurs. For these reasons the business impact of such a problem is
low.
To sum up I just want to reiterate that this is a *good* thing.
Eventual consistency is forcing us to learn more about our domain. It
is forcing us to ask questions that are otherwise often not asked.
Consistency is over-rated.