3

According to http://martinfowler.com/bliki/CQRS.html I believe getOrCreate function is an antipattern.

function getOrCreateObj(something) {
  let f = find(something, db); 
  if (f) return f;
  else return createObj(something);  
}

What should I do to avoid it?

Novellizator
  • 13,633
  • 9
  • 43
  • 65
  • You are creating a global variable `f` there. Better do that as, `find(something, db) || createObj(something)`. Apart from that, you have inconsistent `;` usage. – thefourtheye Nov 24 '15 at 11:40
  • 1
    @thefourtheye that's true, it was only written without checking. But those are only details that don't have much to do with the question itself – Novellizator Nov 24 '15 at 11:42

1 Answers1

2

Better to have side-effect-free functions that return a specific type or null.

So you would have a get and a create method and in the application logic or an abstraction above that check for the existence of something

// pseudo code
get( INT: id ); // Returns SomeObj or NULL
create( INT:id ):: SomeObj;

// In service or application layer or other abstraction
foo = get( 1 ) || create( 1 );
thelastshadow
  • 3,406
  • 3
  • 33
  • 36
  • well, but it does just the same as my code, I only scoped it under a function, didn't I? – Novellizator Nov 24 '15 at 15:06
  • 1
    It is another question, but let me answer it here: It *does* the same, but gives the caller more flexibility. It is called [Inversion of Control](https://en.wikipedia.org/wiki/Inversion_of_control). – Maciej Sz Nov 24 '15 at 15:42
  • @MaciejSz so the key is not to scope that funcitonality into one function, but always have it spread? – Novellizator Nov 27 '15 at 13:14
  • The idea is to write functions where you don't need to inspect the code to use. Side effects, even when commented, mean a programmer using the method needs to understand it's workings. In a complex system with hundreds of functions this can be too much to take in at once, and can radically slow a programmer down. – thelastshadow Nov 28 '15 at 09:46