7

Among other things, the CQRS has a rule that each of the methods has one responsibility. So we can't have this in the model:

public class Store {
    public Item getOrCreateItem(int id)
    {
        //logic
    }
     //....
}

and this in the controller:

Store store = new Store();
Item item = store.getItem(1);

We must have this in the model:

public class Store {
    public Item createItem()
    {
        //logic
    }
    public Item getItem(int id)
    {
        //logic
    }
     //....
}

which leads to this in the controller:

Store store = new Store();
Item item = store.getItem(1);
if (item !== null) {
    Item item = store.createItem();
}

But now we have a lot of code in the controller...

Is there any better way to seperate the methods than to have the extra code in the controller, which should contain little code?

Panzercrisis
  • 3,213

2 Answers2

20

Oh for crying out loud.

The controller has no business knowing what your implementation of getThingy() has behind it. Whether getThingy() creates or passes out a cached copy is none of it's business. The only reason this implementation detail leaked out of the store and into the controller was because you didn't trust the store to just "somehow" get you a thingy. Once you start thinking you know "how", from outside, suddenly you're trapped doing what's expected. That's not abstraction.

If you're thinking "but getters aren't supposed to be factories" then fine. Name it thingy().

If you're thinking "but I have other things that need to get thingy different ways" then fine. Name it controllersThingy().

If all I ask for is a thingy then just give me my thingy. I don't care how. Stop telling me how.

candied_orange
  • 119,268
2

Typically, one would have a Service which would provide this sort of functionality. The Controller would call something like StoreService.EnsureItemExists(1).

The model should probably not do much either - most of the business logic should reside in the service.

autophage
  • 880