Command Query Separation – Applying to Method Creating Object and Returning ID

object-oriented

Let's pretend we have a service that calls a business process. This process will call on the data layer to create an object of type A in the database.

Afterwards we need to call again on another class of the data layer to create an instance of type B in the database. We need to pass some information about A for a foreign key.

In the first method we create an object (modify state) and return it's ID (query) in a single method.

In the second method we have two methods, one (createA) for the save and the other (getId) for the query.

    public void FirstMethod(Info info)
    {
        var id = firstRepository.createA(info);           
        secondRepository.createB(id);
    }

    public void SecondMethod(Info info)
    {
        firstRepository.createA(info);
        var key = firstRepository.getID(info);
        secondRepository.createB(key);
    }

From my understanding the second method follows command query separation more fully. But I find it wasteful and counter-intuitive to query the database to get the object we have just created.

How do you reconcile CQS with such a scenario?

Does only the second method follow CQS and if so is it preferable to use it in this case?

Best Answer

CQS is a guideline rather than an absolute rule. See the wiki article for examples of activities that are impossible under strict CQS.

However, in this case, if you did want to maintain CQS, you could either create the ID on the client side (such as a GUID), or the client could request an ID from the system before creating any objects, which feels cleaner to me than creating the object then querying for it (but is harder than just using an identity column).

Personally I'd just return the ID and call it one of those situations where CQS isn't a good fit.

Another good article with examples: Martin Fowler

Related Topic