Class Concept Changes with Constructor Data – How It Works

constructioninterfacesmethodsobject-oriented

Let's say we're making a parser. One implementation could be:

public sealed class Parser1
{
    public string Parse(string text)
    {
       ...
    }
}

Or we could pass the text to the constructor instead:

public sealed class Parser2
{
    public Parser2(string text)
    {
       this.text = text;
    }

    public string Parse()
    {
       ...
    }
}

Usage is simple in both cases, but what does it mean to enable parameter input to Parser1, compared to the other? What message have I sent to a fellow programmer, when they look at the API? Also, are there any technical advantages/disadvantages in certain cases?

Another question comes up when I realize that an interface would be quite meaningless in the second implementation:

public interface IParser
{
    string Parse();
}

…where an interface on the first one could serve at least some purpose. Does that signify anything in particular, that a class is "interfaceable" or not?

Best Answer

Semantically speaking, in OOP you should only pass the constructor a set of parameters which are needed to build the class - similarly when you call a method, you should only pass it the parameters it needs to execute its business logic.

The parameters that you need to pass in the constructor are parameters which have no sensible default value and if your class is immutable (or indeed a struct) then all-non default properties must be passed.

Regarding your two example:

  • if you pass text to the constructor, it hints that the Parser2 class will be specifically built to parse that instance of text at a later time. It will be a specific parser. This is typically the case when building the class is very expensive or subtle, a RegEx might be compiled in the constructor, so once you hold an instance you can re-use it without having to pay the cost of compiling; another example is initializing the PRNG - it's better if it is done rarely.
  • if you pass text to the method, it signals that Parser1 can be reused to parse different texts by calls.