Code Smell : Stringly Typed

This term "Stringly Typed" were coined from codinghorror site here. It is described as "an implementation that needlessly relies on strings when programmer & refactor friendly options are available". Now, have you ever think that you can replace almost every data type, even functions / methods with string? If not, then you can see it here.

Function / Method as string

This is usually (or primarily) used at procedural programming, especially at console apps. Maybe not many of us used this kind of programming style, but there was an era where this style is a legal once. Take for example:

public void Do(string method){
    if(method == "add"){
        //blocks of code
    }
    else if(method == "subtract"){
        //blocks of code
    }
    else if(method == "divide"){
        //blocks of code
    }
    else if(method == "multiply"){
        //blocks of code
    }
    else{
        Console.Write("Method not found");
    }
}

This style may still valid to use at console apps with user menu input. It can be refactored with constants and enums though. However, it won't give more benefit than it is. But you need to make sure that the code blocks inside each condition will be encapsulated within another function / class. Why? Because if you don't, it tends to become god object, which is a very large code part, hard to maintenance and simple change can break a whole function.

Or, you can simply change the condition matching with something like string map. For example in this error-prone code:

public void Do(string method){
    Dictionary<string, Action> map = new Dictionary<string, Action>({
        { "add", Add },
        { "subtract", Subtract },
        { "divide", Divide },
        { "multiply", Multiply },
    };
    // method existance check
    // execute the method
    map[method]();
}
Though this is better at preventing you from creating god object.

No Data Type Except String

Do you know that with string, or array of strings you can represent any class model? This can be done in many ways:
  • Dictionary<string,string>. It is not wrong if used as map, but it is wrong if used as data model representative. IEnumerable<Dictionary<string, string>> is the evil brother of previous IEnumerable<Dictionary<string, object>>
  • Delimiter separated value. |Henry Ford|Male|Baker Street| is a valid data model representation by string. Even in most data transfer format using delimited string. Or I believe in memory processing also, they tend use header and footer with string inside.
  • Tag-based value. Such as JSON: {key : value}, xml tag: <element>content</element>, BB tag: [TAG]Content[/TAG]. And so on.
The data model representation with string is a valid one, but it becomes invalid if you use that as a replacement to class as data model. That is because you need parser (for more complex data type), and you will end up with string to data type conversion in the entire applications.

Conclusion

We have many advanced features to eliminate stringly typed code, such as Class/Struct, delegates, etc. String-based logical processing has it's own case to be used. But those case are relatively small and can be easily identified (such as mapping). In other identified case, when it is possible to use programming terms (class, functions, data type), for other developer or you future self's sake, don't create stringly type code.

No comments: