Is use of VO´s (POCO) a bad design
pattern? Some people say that all
domain logic of an object needs to be
together in that object.
I think there's a lot of confusion here because there are two almost completely contradictory definitions of "Value Object".
- One is "An object with value semantics", i.e. immutable and often validated for correctness at construction.
- Another is "An object that has state but no logic". I think that's what you mean. It's better to call this a Data Transfer Object, since that expression is better defined.
POCO/POJO is also not a fitting expression because it does not mean absence of logic either, only that no specific superclass, interface or bytecode enhancement is required.
As for your question: having a domain model in classes without logic for no other reason than having seen other people doing it like that and having a name for it is indeed very bad design - it's an anti-pattern known as anemic domain model. Unfortunately, there have been a number of badly designed frameworks (now generally abandoned) that required and promoted this "pattern".
It ignores the fundamental idea of object orientation: encapsulating data with the logic that operates on it, and it generally leads to verbose, inflexible and fragile code because the external logic now needs to be called explicitly and passed the model, it becomes much harder to ensure that invalid data is not passed around, and the knowledge about the structure of the domain model is spread around widely.
That being said, it's definitely not true that "all domain logic of an object needs to be together in that object" - sometimes there are good reasons to extract some of the domain logic and keep it in separate classes:
- When it's not really domain logic but a technical aspect, like persistence, that should be in a separate layer
- when the logic is different in different parts of the application
- generally, when it's so complex that the domain classes would become too big, and you need to structure it more.
But generally, the domain logic concerning an object should be part of that object, unless you have a specific reason to put it somewhere else.