In our codebase we have a lot of controllers with a very similar structure:


if @my_model.update_attributes(params)
    return render_object(@my_model)
    return render_validation_error(@my_model)

Although the structure is not exactly the same everywhere, it seems feasible to refactor. It could look like:

def update_model_and_render(model)

Certainly, we would save a lot of lines. It would also be helpful for future programmers implementing similar functionality. Calling the new refactored function would prevent them from forgetting to add the @my_model.update_owner() line.

The problem with the new function is that it would be producing a side-effect and also returning a value. Clearly, We would be breaking Command-Query Separation (the new function would be referentially opaque).

Is it ok to bend the rule in cases like this to be more DRY?.

In a lot of code that I have seen, this happens usually at the boundaries of the system (like a controller, where mutations do happen but we always return a value), but I am not sure if there is anything else I could be missing.

  • 2
    It's OK to break the rules if it serves your purposes. Just understand fully what the tradeoffs are. Dec 18, 2017 at 17:06
  • Robert, first and foremost thanks for answering!. I think I get the spirit of CQS and how it gives you different levels of confidence over mutations and queries, the effects that it has when composing software. But I was wondering if there is a (not sure how to put it) more academic perspective or principle written somewhere about how you should implement this especially at the boundaries of your system. Exactly as you said, I wonder if I miss some tradeoff for a case like this, where it seems to me, you want DRY over CQS. Thanks for your time.
    – Jacob
    Dec 18, 2017 at 17:19


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.