I understood the command and query separation principle as : A function must either return (compute) a value and have no side effects either return void and have side effects (change state of its context).
This definition is quite nice to work with because it's very easy in concept. However it seems to fall flat when using this sort of factory:
class House {
static House? _cachedInstance; // private in dart
House.privateConstructor();
factory() create() {
if (_cachedInstance == null) {
_cachedInstance = House.privateConstructor();
}
return _cachedInstance!;
}
}
Some state is changed here (cached instance is created).
Wikipedia article says about CQS "asking a question should not change the answer." Which is not the case here though.
So I'm wondering if my original understanding is incorrect or partially incorrect.
I would say singletons do break CQS, I don't think this is such a bad thing, it is the kind of thing where the advantages of CQS don't really show because of how simple the code is, but here is a way to implement a singleton without breaking CQS, side-effect is that the instance getter is nullable
class Singleton {
static Singleton? _instance;
static Singleton? get instance => _instance;
Singleton._private();
static void ensureCreated() {
_instance ??= Singleton._private();
}
}
this way:
Singleton.ensureCreated();
Singleton singleton = Singleton.instance!;