How much work should the constructor for an HTML parsing class do?

前端 未结 19 1907
悲&欢浪女
悲&欢浪女 2020-12-23 09:55

How much work is it reasonable for an object constructor to do? Should it simply initialize fields and not actually perform any operations on data, or is it okay to have it

19条回答
  •  自闭症患者
    2020-12-23 10:32

    "Should the parsing code be placed within a void parseHtml() method and the accessors only return valid values once this method is called?"

    Yes.

    "The design of the class is such that the class' constructor does the parsing"

    This prevents customization, extension, and -- most importantly -- dependency injection.

    There will be times when you want to do the following

    1. Construct a parser.

    2. Add Features to the parser: Business Rules, Filters, Better Algorithms, Strategies, Commands, whatever.

    3. Parse.

    Generally, it's best to do as little as possible in a constructor so that you are free to extend or modify.


    Edit

    "Couldn't extensions simply parse the extra information in their constructors?"

    Only if they don't have any kind of features that need to be injected. If you want to add features -- say a different strategy for constructing the parse tree -- your subclasses have to also manage this feature addition before they parse. It may not amount to a simple super() because the superclass does too much.

    "Also, parsing in the constructor allows me to fail early"

    Kind of. Failing during construction is a weird use case. Failing during construction makes it difficult to construct a parser like this...

    class SomeClient {
        parser p = new Parser();
        void aMethod() {...}
    }
    

    Usually a construction failure means you're out of memory. There's rarely a good reason to catch construction exceptions because you're doomed anyway.

    You're forced to build the parser in a method body because it has too complex arguments.

    In short, you've removed options from the clients of your parser.

    "It's inadvisable to inherit from this class to replace an algorithm."

    That's funny. Seriously. It's an outrageous claim. No algorithm is optimal for all possible use cases. Often a high-performance algorithm uses a lot of memory. A client may want to replace the algorithm with a slower one that uses less memory.

    You can claim perfection, but it's rare. Subclasses are the norm, not an exception. Someone will always improve on your "perfection". If you limit their ability to subclass your parser, they'll simply discard it for something more flexible.

    "I don't see needing step 2 as described in the answer."

    A bold statement. Dependencies, Strategies and related injection design patterns are common requirements. Indeed, they're so essential for unit testing that a design which makes it difficult or complex often turns out to be a bad design.

    Limiting the ability to subclass or extend your parser is a bad policy.

    Bottom Line.

    Assume nothing. Write a class with as few assumptions about it's use cases as possible. Parsing at construction time makes too many assumptions about client use cases.

提交回复
热议问题