Diskussion mit Greg Young über CRUD und task based UI’s

Habe eben im Archiv von Herding Code eine Perle gefunden. Obwohl bereits fast ein Jahr alt, ist diese Diskussion mit CQRS Experten Greg Young immer noch hoch aktuell und jedem Software Entwickler zu empfehlen. Im Wesentlichen sagt Greg, dass die meisten Anwendungen nicht mit CRUD abgebildet werden sollten, sondern mit Systemen, die in der Realität benötigte Aufgaben abbilden.

Using Deep Copy for Mock Repositories

Recently in a DDD project I needed a mock implementation of a repository interface for implementing my unit tests. In my first attempt I used a simple HashMap for storing my domain objects in my mock implementation. This worked fine in most situations but didn’t behave like the real database implementation in the following case:

  1. Request object from repository
  2. Make changes to the object
  3. Don’t save the object back to simulate cancelation of an editing process by the user
  4. Request the same object from the repository again

With the real database implementation I would get the object without the changes from the editing process, since the changes never got saved. But in the mock implementation the changes were visible. The reason is simple: Since the mock repository gives me only a reference to the object in the HashMap, all changes to this object are visible to all of the other references.

I found the following solution for this problem: Making deep copies in the mock repository for all objects passed in and out. That way changes to an object are never made to the object in the HashMap until I explicitly save the object.

For making deep copies I used the method described by Philip Isenhour on his website.

A simple mock repository implementation looks like this:

public abstract class MemoryRepositoryBase<K, T> {

 protected Map<K, T> map = new HashMap<K, T>();

 public T findById(K id) {
   T obj = map.get(id);
   if (obj != null) {
     return (T) DeepCopy.copy(obj);
   return null;

 public void save(T obj) {
   T copy = (T) DeepCopy.copy(obj);
   map.put(copy.getId(), copy);