Over the years i have seen multiple cases where data is accessed and/or manipulated using a representative value which is internally resolved to the right object/data-field/algorithm.Some examples:// 1. Provide same logger globally using it's nameauto myLogger = LoggingService.getLogger(myLogger)// 2. Get person object using a unique idauto person = PersonCatalog.getPerson(12345)// 3. Get the left child of a B-Tree nodeauto lnode = BTreeNode.getNode(left)// 4. Make player character do something based off a commandplayerCharacter.performAction(move_north)I understand, why one would use this approach for the logger, as you don't have to pass around concrete objects to a Logger instance throughout the whole program. I can also see the merit in the second example, as it could provide an interface to a dictionary or a database lookup.But the third and fourth example in contrast smell of design flaws.Does this kind of design have a name and is it a viable strategy for more than just a couple of special scenarios?
Is accessing data using a representative value a viable strategy?
design
I agree, the latter two appear to be code smells, and the first one also. But I believe the contrast posed in this question has more to do with choosing the appropriate data structures than with specific patterns. I'll go over each one, starting with the one that seems fine.The #2 above looks okay (assuming the magic string is just for brevity) and uses the concept of an identifier. It's less a pattern and more of a basic concept used long before computers existed. In this case, the chosen identifier as a number string.The #1 is a smell because it's unclear what should be passed in to get the right logger. Is myLogger an internal name, or a class to instantiate, or a connection string? I can't tell from this call, and I've seen all of those options used before. If I again assume the magic string is for brevity, it could be alright if the variable name and/or a comment clarifies it.The #3 is a smell because it's using a very fluid and easy-to-get-wrong structure (a string identifier) to represent a very concrete concept. In fact, there are 2 or so correct strings you can pass in and virtually infinite incorrect strings. This is concrete enough that it should ideally be represented by a design-time validated structure like a class. Then when you get a member name wrong, the code won't even compile or will give a syntax error. The structure itself is important enough that the compiler/interpreter shouldn't even run it if incorrect.The #4 is a smell in a similar way to #3 (no validated structure) and #1 (lack of clarity), but less specific than B-tree code in #3. (Assuming you have reasons for not representing actions using methods/functions, f.ex. client/server.) You could represent this with a pattern or two. You could use messaging or even the GOF command pattern, depending on the specific application. Having messages as concrete classes would both give your inputs a validated structure and give your callers a well-defined means to communicate with you.In summary, most of these examples highlight the need to choose the appropriate data structure. Using strings to activate code branches is not nearly specific enough for well-known algorithms like b-trees. But it might be okay for a database connection. Choose wisely.