or keep a common Tag class despite it has no business sense?
Does not refer to the same business reality
Not all code directly translates to or stems from a business need. If a common class makes sense for a particular code design, then there's nothing wrong with using it. Assuming the design itself is appropriate of course.
Since those two type of tags can never be interchanged (John cannot be made of bricks)
But can you state for a fact that there will never be a tag which may overlap? It's easy to gloss over possible future tags that overlap if your current ones simply happen to not overlap.
should I create two child-classes with all properties deriving from a base Tag class like ShopTag and CustomerTag or keep a common Tag
It very much depends on several points:
- Is there a direct need to enforce validation here instead of relying on the tag creators to do the right thing?
Take StackExchange for an example. I can tag my question however I like, the sytem does not block it in any way. But there is an implicit expectation that the users will sanitize any bad entries that may occur.
Trying to write an algorithm to do so takes a lot of effort and there can be a lot of false positives and negatives, so the effort is not worth it. The same can apply to your case, you haven't really shown any reason to want to actively enforce this other than "I could do it".
- Are you going to expect tag creators to always know in advance which entity a tag describes?
Even though it makes sense to you, it might not make sense to end users to categorize tags like this. You're still going to rely on your tag creators to categorize tags correctly - so why can't you then just rely on these users to apply tags with the same level of correctness?
- Will there never be any overlap between entities that a tag might apply to?
- or if there is, how do you expect to handle that case?
If you need to start handling overlap, it's going to get really hard, because you're going to have to design a validation system that is really complex to develop, and really complex to wield by your tag creators.
That being said, there is a range of options you could take here:
- Let the users manage their own content
- Create an enum type (
TagType) and give the Tag class a property of that enum type.
- Make specific
Tag classes for each type and use inheritance of a generic base class to specify which tag type a certain object uses.
- Store these tags in different tables and give each entity a FK (albeit with a cross table due to many-to-many) to their specific tag table.
You haven't really shown why you need to have this enforced/validated. Without a direct need, I suggest you err on the side of not writing something you don't know you need yet.
Some direct feedback to your question:
Prevents other developpers to mix them up later on
Wait, is it developers who are using specific tags, or end users? Because tags tend to be a sort of "free form categories" used by end users to sort their data.
If specific tags are a developer concern, then these specific tags are effectively a constant in the codebase? I mean that regardless of where the data is stored, your code expects certain tags to exist - these cannot be created or deleted by end users after release?
Improves readability
That's highly arguable. More complexity detracts from readability. Since you haven't expressed why you need this, it's unclear whether it's going to add or detract from the readability.
Comes from different databases, I have no control on that point (should I take that in consideration?)
Do these databases live independent lives? If one database changes its tags (let's say tag names now come as a list of translations), does that mean the other might not receive the same update?
If they are deployed and versioned independently, then you're always going to need separate classes, even if these tags could be freely mixed.
Whether you then still use a base class very much depends on whether you expect to have code that can operate on either entity without needing to know its specific type (nor the specific type of its tags).
class TaggedObject<TTagType> where TTagType : TagBase { public IEnumerable<TTagType> Tags; }andclass Shop : TaggedObject<ShopTag> { }. I'm not saying OP needs it here, I'm just showing an example use case for that base class.