I often need to decide between these two strategies for the object design:
An object that is fully initialised and ready to use after its construction. The constructor often requires a complex list of parameters, hence the object initialisation is nontrivial. All objects having it as a member variable will also need nontrivial constructors. This may lead to code whose complexity is concentrated at object constructors, often making the code hard to follow.
An object with default constructor. The object variables are set individually by means of setter methods. This approach has the disadvantage that most methods need to check whether the object is fully initialized, hence complicating the code.
What is your personal preference between the two, and how do you decide when to use one or the other?
In my opinion if a constructor is getting too bloated it's time to split up your object in more different, smaller objects. This might be impossible in some rare cases, but in most cases it can be done.
Neither.
Huge parameter lists indicates the object does too much. Lots of properties that need to be set before the object can have a valid and useful output indicates it does too much.
So neither approach is a solution as far as I'm concerned.
There are lots of ways to break these things up, but outside of a specific scenario, the only rule is, "It needs doing".
Aggregation into other objects, "controller" classes, various communicator patterns. Are some categories first class objects, can some be hidden in the implementation.
I don't accept that the two options you present are the only ones, except possibly from a pragmatic point of view in terms of getting the code out of the door. Which one I was then forced to choose, would simply depend on how many calls to the constructor with different parameters the code required, versus how much validation would be needed to confirm all the properties were set, and possibly the impact on unit tests, which because the object is a mess would be unwieldy or limited.
If a constructor takes many arguments — you call this non-trivial object initialisation — and you don't want to split up your class into smaller ones, then one alternative is to put the parameters into a Parameter Object and then only pass that object to the constructor.
Second, I believe that you should distinguish between...
object properties that absolutely must be set if the object is supposed to do its work, and there is no sensible default value. These properties should be initialised via a constructor parameter.
object properties that can be set optionally, or overridden, by the user. While you might initialise such properties in the constructor, you don't have to have a separate constructor parameter for them. Instead, you might assign a sensible default value to them that still can be overridden by the user through a setter method.
There is also an alternative to the first type of properties (those that must absolutely have a user-provided value): properties which are provided through overriding an abstract getter in a derived class:
abstract class ComplicatedFoo {
protected abstract T getSomeDependency(); // replaces required ctor parameter
}
P.S.: The book "Dependency Injection" by Dhanji R. Prasanna (Manning Publications) gives a good overview of the various ways how to initialise an object.
It's always good to initialize all your variables in the constructor, but to a default value. If it is difficult to get the value of the variable (for example, you have to call some function somewhere to get that value), you may set that value to an invalid one and then later you set the correct value.
It is not a good idea to make the constructor so complex, because you can't return an error in the constructor (I don't know if it is ok to throw an exception in the constructor or not, because I particulary don't like trhowing exceptions anywhere). Also, you can't call virtual functions there, and so on.
An approach I like when the construction of the class is complex is to create an "init" function. Then I can do something like:
Person::Person()
{
age = -1;
...
}
int Person::Init()
{
age = functionThatReturnsTheAgeFromSomeDB();
if (age == -1 )
{
return DB_ERROR;
}
...
}
And so on.
Related
I have a class which represents a set of numbers. The constructor takes three arguments: startValue, endValue and stepSize.
The class is responsible for holding a list containing all values between start and end value taking the stepSize into consideration.
Example: startValue: 3, endValue: 1, stepSize = -1, Collection = { 3,2,1 }
I am currently creating the collection and some info strings about the object in the constructor. The public members are read only info strings and the collection.
My constructor does three things at the moment:
Checks the arguments; this could throw an exception from the constructor
Fills values into the collection
Generates the information strings
I can see that my constructor does real work but how can I fix this, or, should I fix this? If I move the "methods" out of the constructor it is like having init function and leaving me with an not fully initialized object. Is the existence of my object doubtful? Or is it not that bad to have some work done in the constructor because it is still possible to test the constructor because no object references are created.
For me it looks wrong but it seems that I just can't find a solution. I also have taken a builder into account but I am not sure if that's right because you can't choose between different types of creations. However single unit tests would have less responsibility.
I am writing my code in C# but I would prefer a general solution, that's why the text contains no code.
EDIT: Thanks for editing my poor text (: I changed the title back because it represents my opinion and the edited title did not. I am not asking if real work is a flaw or not. For me, it is. Take a look at this reference.
http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
The blog states the problems quite well. Still I can't find a solution.
Concepts that urge you to keep your constructors light weight:
Inversion of control (Dependency Injection)
Single responsibility principle (as applied to the constructor rather than a class)
Lazy initialization
Testing
K.I.S.S.
D.R.Y.
Links to arguments of why:
How much work should be done in a constructor?
What (not) to do in a constructor
Should a C++ constructor do real work?
http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
If you check the arguments in the constructor that validation code can't be shared if those arguments come in from any other source (setter, constructor, parameter object)
If you fill values into the collection or generate the information strings in the constructor that code can't be shared with other constructors you may need to add later.
In addition to not being able to be shared there is also being delayed until really needed (lazy init). There is also overriding thru inheritance that offers more options with many methods that just do one thing rather then one do everything constructor.
Your constructor only needs to put your class into a usable state. It does NOT have to be fully initialized. But it is perfectly free to use other methods to do the real work. That just doesn't take advantage of the "lazy init" idea. Sometimes you need it, sometimes you don't.
Just keep in mind anything that the constructor does or calls is being shoved down the users / testers throat.
EDIT:
You still haven't accepted an answer and I've had some sleep so I'll take a stab at a design. A good design is flexible so I'm going to assume it's OK that I'm not sure what the information strings are, or whether our object is required to represent a set of numbers by being a collection (and so provides iterators, size(), add(), remove(), etc) or is merely backed by a collection and provides some narrow specialized access to those numbers (such as being immutable).
This little guy is the Parameter Object pattern
/** Throws exception if sign of endValue - startValue != stepSize */
ListDefinition(T startValue, T endValue, T stepSize);
T can be int or long or short or char. Have fun but be consistent.
/** An interface, independent from any one collection implementation */
ListFactory(ListDefinition ld){
/** Make as many as you like */
List<T> build();
}
If we don't need to narrow access to the collection, we're done. If we do, wrap it in a facade before exposing it.
/** Provides read access only. Immutable if List l kept private. */
ImmutableFacade(List l);
Oh wait, requirements change, forgot about 'information strings'. :)
/** Build list of info strings */
InformationStrings(String infoFilePath) {
List<String> read();
}
Have no idea if this is what you had in mind but if you want the power to count line numbers by twos you now have it. :)
/** Assuming information strings have a 1 to 1 relationship with our numbers */
MapFactory(List l, List infoStrings){
/** Make as many as you like */
Map<T, String> build();
}
So, yes I'd use the builder pattern to wire all that together. Or you could try to use one object to do all that. Up to you. But I think you'll find few of these constructors doing much of anything.
EDIT2
I know this answer's already been accepted but I've realized there's room for improvement and I can't resist. The ListDefinition above works by exposing it's contents with getters, ick. There is a "Tell, don't ask" design principle that is being violated here for no good reason.
ListDefinition(T startValue, T endValue, T stepSize) {
List<T> buildList(List<T> l);
}
This let's us build any kind of list implementation and have it initialized according to the definition. Now we don't need ListFactory. buildList is something I call a shunt. It returns the same reference it accepted after having done something with it. It simply allows you to skip giving the new ArrayList a name. Making a list now looks like this:
ListDefinition<int> ld = new ListDefinition<int>(3, 1, -1);
List<int> l = new ImmutableFacade<int>( ld.buildList( new ArrayList<int>() ) );
Which works fine. Bit hard to read. So why not add a static factory method:
List<int> l = ImmutableRangeOfNumbers.over(3, 1, -1);
This doesn't accept dependency injections but it's built on classes that do. It's effectively a dependency injection container. This makes it a nice shorthand for popular combinations and configurations of the underlying classes. You don't have to make one for every combination. The point of doing this with many classes is now you can put together whatever combination you need.
Well, that's my 2 cents. I'm gonna find something else to obsess on. Feedback welcome.
As far as cohesion is concerned, there's no "real work", only work that's in line (or not) with the class/method's responsibility.
A constructor's responsibility is to create an instance of a class. And a valid instance for that matter. I'm a big fan of keeping the validation part as intrinsic as possible, so that you can see the invariants every time you look at the class. In other words, that the class "contains its own definition".
However, there are cases when an object is a complex assemblage of multiple other objects, with conditional logic, non-trivial validation or other creation sub-tasks involved. This is when I'd delegate the object creation to another class (Factory or Builder pattern) and restrain the accessibility scope of the constructor, but I think twice before doing it.
In your case, I see no conditionals (except argument checking), no composition or inspection of complex objects. The work done by your constructor is cohesive with the class because it essentially only populates its internals. While you may (and should) of course extract atomic, well identified construction steps into private methods inside the same class, I don't see the need for a separate builder class.
The constructor is a special member function, in a way that it constructor, but after all - it is a member function. As such, it is allowed to do things.
Consider for example c++ std::fstream. It opens a file in the constructor. Can throw an exception, but doesn't have to.
As long as you can test the class, it is all good.
It's true, a constructur should do minimum of work oriented to a single aim - successful creaation of the valid object. Whatever it takes is ok. But not more.
In your example, creating this collection in the constructor is perfectly valid, as object of your class represent a set of numbers (your words). If an object is set of numbers, you should clearly create it in the constructor! On the contrary - the constructur does not perform what it is made for - a fresh, valid object construction.
These info strings call my attention. What is their purpose? What exactly do you do? This sounds like something periferic, something that can be left for later and exposed through a method, like
String getInfo()
or similar.
If you want to use Microsoft's .NET Framework was an example here, it is perfectly valid both semantically and in terms of common practice, for a constructor to do some real work.
An example of where Microsoft does this is in their implementation of System.IO.FileStream. This class performs string processing on path names, opens new file handles, opens threads, binds all sorts of things, and invokes many system functions. The constructor is actually, in effect, about 1,200 lines of code.
I believe your example, where you are creating a list, is absolutely fine and valid. I would just make sure that you fail as often as possible. Say if you the minimum size higher than the maximum size, you could get stuck in an infinite loop with a poorly written loop condition, thus exhausting all available memory.
The takeaway is "it depends" and you should use your best judgement. If all you wanted was a second opinion, then I say you're fine.
It's not a good practice to do "real work" in the constructor: you can initialize class members, but you shouldn't call other methods or do more "heavy lifting" in the constructor.
If you need to do some initialization which requires a big amount of code running, a good practice will be to do it in an init() method which will be called after the object was constructed.
The reasoning for not doing heavy lifting inside the constructor is: in case something bad happens, and fails silently, you'll end up having a messed up object and it'll be a nightmare to debug and realize where the issues are coming from.
In the case you describe above I would only do the assignments in the constructor and then, in two separate methods, I would implement the validations and generate the string-information.
Implementing it this way also conforms with SRP: "Single Responsibility Principle" which suggests that any method/function should do one thing, and one thing only.
I am from a C# background and have been doing programming for quite some time now. But only recently i started giving some thoughts on how i program. Apparently, my OOP is very bad.
I have a few questions maybe someone can help me out. They are basic but i want to confirm.
1- In C#, we can declare class properties like
private int _test;
and there setter getters like
public int Test {get; set;}
Now, lets say i have to use this property inside the class. Which one will i use ? the private one or the public one ? or they both are the same ?
2- Lets say that i have to implement a class that does XML Parsing. There can be different things that we can use as input for the class like "FILE PATH". Should i make this a class PROPERTY or should i just pass it as an argument to a public function in the class ? Which approach is better. Check the following
I can create a class property and use like this
public string FilePath {get; set;}
public int Parse()
{
var document = XDocument.Load(this.FilePath);
.........//Remaining code
}
Or
I can pass the filepath as a parameter
public int Parse(string filePath)
On what basis should i make a decision that i should make a property or i should pass something as argument ?
I know the solutions of these questions but i want to know the correct approach. If you can recommend some video lectures or books that will be nice also.
Fields vs Properties
Seems like you've got a few terms confused.
private int _test;
This is an instance field (also called member).
This field will allow direct access to the value from inside the class.
Note that I said "inside the class". Because it is private, it is not accessible from outside the class. This is important to preserve encapsulation, a cornerstone of OOP. Encapsulation basically tells us that instance members can't be accessed directly outside the class.
For this reason we make the member private and provide methods that "set" and "get" the variable (at least: in Java this is the way). These methods are exposed to the outside world and force whoever is using your class to go trough your methods instead of accessing your variable directly.
It should be noted that you also want to use your methods/properties when you're inside the current class. Each time you don't, you risk bypassing validation rules. Play it safe and always use the methods instead of the backing field.
The netto result from this is that you can force your logic to be applied to changes (set) or retrieval (get). The best example is validation: by forcing people to use your method, your validation logic will be applied before (possibly) setting a field to a new value.
public int Test {get; set;}
This is an automatically implemented property. A property is crudely spoken an easier way of using get/set methods.
Behind the scenes, your code translates to
private int _somevariableyoudontknow;
public void setTest(int t){
this._somevariableyoudontknow = t;
}
public int getTest(){
return this._somevariableyoudontknow;
}
So it is really very much alike to getters and setters. What's so nice about properties is that you can define on one line the things you'd do in 7 lines, while still maintaining all the possibilities from explicit getters and setters.
Where is my validation logic, you ask?
In order to add validation logic, you have to create a custom implemented property.
The syntax looks like this:
private int _iChoseThisName;
public int Test {
get {
return _iChoseThisName;
}
set {
if(value > 5) { return _iChoseThisName; }
throw new ArgumentException("Value must be over 5!");
}
}
Basically all we did was provide an implementation for your get and set. Notice the value keyword!
Properties can be used as such:
var result = SomeClass.Test; // returns the value from the 'Test' property
SomeClass.Test = 10; // sets the value of the 'Test' property
Last small note: just because you have a property named Test, does not mean the backing variable is named test or _test. The compiler will generate a variablename for you that serves as the backing field in a manner that you will never have duplication.
XML Parsing
If you want your second answer answered, you're going to have to show how your current architecture looks.
It shouldn't be necessary though: it makes most sense to pass it as a parameter with your constructor. You should just create a new XmlParser (random name) object for each file you want to parse. Once you're parsing, you don't want to change the file location.
If you do want this: create a method that does the parsing and let it take the filename as a parameter, that way you still keep it in one call.
You don't want to create a property for the simple reason that you might forget to both set the property and call the parse method.
There are really two questions wrapped in your first question.
1) Should I use getters and setters (Accessors and Mutators) to access a member variable.
The answer depends on whether the implementation of the variable is likely to change. In some cases, the interface type (the type returned by the getter, and set by the setter) needs to be kept consistent but the underlying mechanism for storing the data may change. For instance, the type of the property may be a String but in fact the data is stored in a portion of a much larger String and the getter extracts that portion of the String and returns it to the user.
2) What visibility should I give a property?
Visibility is entirely dependent on use. If the property needs to be accessible to other classes or to classes that inherit from the base class then the property needs to be public or protected.
I never expose implementation to external concerns. Which is to say I always put a getter and setter on public and protected data because it helps me ensure that I will keep the interface the same even if the underlying implementation changes. Another common issue with external changes is that I want a chance to intercept an outside user's attempt to modify a property, maybe to prevent it, but more likely to keep the objects state in a good or safe state. This is especially important for cached values that may be exposed as properties. Think of a property that sums the contents of an array of values. You don't want to recalculate the value every time it is referenced so you need to be certain that the setter for the elements in the array tells the object that the sum needs to be recalculated. This way you keep the calculation to a minimum.
I think the second question is: When do I make a value that I could pass in to a constructor public?
It depends on what the value is used for. I generally think that there are two distinct types of variables passed in to constructors. Those that assist in the creation of the object (your XML file path is a good example of this) and those that are passed in because the object is going to be responsible for their management. An example of this is in collections which you can often initialize the collection with an array.
I follow these guidelines.
If the value passed in can be changed without damaging the state of the object then it can be made into a property and publicly visible.
If changing the value passed in will damage the state of the object or redefine its identity then it should be left to the constructor to initialize the state and not be accesible again through property methods.
A lot of these terms are confusing because of the many different paradigms and languages in OO Design. The best place to learn about good practices in OO Design is to start with a good book on Patterns. While the so-called Gang of Four Book http://en.wikipedia.org/wiki/Design_Patterns was the standard for many years, there have since been many better books written.
Here are a couple resources on Design Patterns:
http://sourcemaking.com/design_patterns
http://www.oodesign.com/
And a couple on C# specific.
http://msdn.microsoft.com/en-us/magazine/cc301852.aspx
http://www.codeproject.com/Articles/572738/Building-an-application-using-design-patterns-and
I can possibly answer your first question. You asked "I have to use this property inside the class." That sounds to me like you need to use your private variable. The public method which you provided I believe will only do two things: Allow a client to set one of your private variables, or to allow a client to "see" (get) the private variable. But if you want to "use this property inside the class", the private variable is the one that should be your focus while working with the data within the class. Happy holidays :)
The following is my personal opinion based on my personal experience in various programming languages. I do not think that best practices are necessarily static for all projects.
When to use getters, when to use private instance variables directly
it depends.
You probably know that, but let's talk about why we usually want getters and setters instead of public instance variables: it allows us to aquire the full power of OOP.
While an instance variable is just some dump piece of memory (the amount of dumbness surely depends on the language you're working in), a getter is not bound to a specific memory location. The getter allows childs in the OOP hirarchy to override the behaviour of the "instance variable" without being bound to it. Thus, if you have an interface with various implementations, some may use ab instance variable, while others may use IO to fetch data from the network, calculate it from other values, etc.
Thus, getters do not necessarily return the instance variable (in some languages this is more complicated, such as c++ with the virtual keyword, but I'll try to be language-independent here).
Why is that related to the inner class behaviour? If you have a class with a non-final getter, the getter and the inner variable may return different values. Thus, if you need to be sure it is the inner value, use it directly. If you, however, rely on the "real" value, always use the getter.
If the getter is final or the language enforces the getter to be equal (and this case is way more common than the first case), I personally prefer accessing the private field directly; this makes code easy to read (imho) and does not yield any performance penalty (does not apply to all languages).
When to use parameters, when to use instance variables/properties
use parameters whereever possible.
Never use instance variables or properties as parameters. A method should be as self-contained as possible. In the example you stated, the parameterized version is way better imo.
Intance variables (with getters or not) are properties of the instance. As they are part of the instance, they should be logically bound to it.
Have a look at your example. If you hear the word XMLParser, what do you think about it? Do you think that a parser can only parse a single file it is bound to? Or do you think that a parser can parse any files? I tend to the last one (additionally, using an instance variable would additionally kill thread-safety).
Another example: You wish to create an XMLArchiver, taking multiple xml documents into a single archive. When implementing, you'd have the filename as a parameter of the constructor maybe opening an outputstream towards the file and storing a reference to it as an instance variable. Then, you'd call archiver.add(stuff-to-add) multiple times. As you see, the file (thus, the filename) is naturally bound to the XMLArchiver instance, not to the method adding files to it.
Given some type as follows:
class Thing {
getInfo();
isRemoteThing();
getRemoteLocation();
}
The getRemoteLocation() method only has a defined result if isRemoteThing() returns true. Given that most Things are not remote, is this an acceptable API? The other option I see is to provide a RemoteThing subclass, but then the user needs a way to cast a Thing to a RemoteThing if necessary, which just seems to add a level of indirection to the problem.
Having an interface include members which are usable on some objects that implement the interface but not all of them, and also includes a query method to say which interface members will be useful, is a good pattern in cases where something is gained by it.
Examples of reasons where it can be useful:
If it's likely than an interface member will be useful on some objects but not other instances of the same type, this pattern may be the only one that makes sense.
If it's likely that a consumer may hold references to a variety of objects implementing the interface, some of which support a particular member and some of which do not, and if it's likely that someone with such a collection would want to use the member on those instances which support it, such usage will be more convenient if all objects implement an interface including the member, than if some do and some don't. This is especially true for interface members like IDisposable.Dispose whose purpose is to notify the implementation of something it may or may not care about (e.g. that nobody needs it anymore and it may be abandoned without further notice), and ask it to do whatever it needs to as a consequence (in many cases nothing). Blindly calling Dispose on an IEnumerable<T> is faster than checking whether an implementation of IEnumerable also implements IDisposable. Not only the unconditional call faster than checking for IDisposable and then calling it--it's faster than checking whether an object implements IDisposable and finding out that it doesn't.
In some cases, a consumer may use a field to hold different kinds of things at different times. As an example, it may be useful to have a field which at some times will hold the only extant reference to a mutable object, and at other times will hold a possibly-shared reference to an immutable object. If the type of the field includes mutating methods (which may or may not work) as well as a means of creating a new mutable instance with data copied from an immutable one, code which receives an object and might want to mutate the data can store a reference to the passed-in object. If and when it wants to mutate the data, it can overwrite the field with a reference to a mutable copy; if it never ends up having to mutate the data, however, it can simply use the passed-in immutable object and never bother copying it.
The biggest disadvantage of having interfaces include members that aren't always useful is that it imposes more work on the implementers. Thus, people writing interfaces should only include members whose existence could significantly benefit at least some consumers of almost every class implementing the interface.
Why should this not be acceptable? It should, however, be clearly documented. If you look at the .net class libraries or the JDK, there are collection interfaces defining methods to add or delete items, but there are unmodifiable classes implementing these interfaces. It is a good idea in this case - as you did - to provide a method to query the object if it has some capabilities, as this helps you avoid exceptions in the case that the method is not appropriate.
OTOH, if this is an API, it might be more appropriate to use an interface than a class.
Currently we are writing our bachelor thesis about the implementation of a Compiler for an academic object-oriented mini programming language.
We want to be precise in our documentation, and we're currently discussing if a constructor is a routine.
What we think points out that a constructor is a routine is that it has a block of Commands, Parameters and local variables. Despite the missing name, all other attributes of other routines are given.
What we think points out that a constructor is not a routine is that it can only be called once per instance.
We are not sure if this question has a clear answer, or if the definition is different from theory to theory.
We would be happy if someone could give a pointer to some literature about this semantic question.
Best
Edit: Some Information about how we name specific things in our Language:
We have functions and procedures. Functions do have a return value, procedures don't.
A constructor is like an unnamed procedure (without explicit return value)
a constructor is called implicit, java like: x := new X(1, new Y())
Parameters are defined during the definition of a constructor. The own instance (this) is not considered a parameter but provided implicitly
Thanks for your answers so far, they're helping with the though process.
This depends on language - and for this academic language - I would not say that a constructor is a routine. I say that because in not saying that it is a routine, a separation is kept: unless the language explicitly unifies routines/functions/constructors, don't say it does :)
Now, consider these counter-examples (and there are many more, I am sure):
Languages like Eiffel allow giving constructors different names (which I think is awesome and wish was used more).
Languages like Ruby don't have a "new" operator and invoking a constructor appears as invoking any (class) method. Ruby doesn't even have a way of signaling that a method acts as a constructor (or factory method, as it were).
Constructors in languages like JavaScript are just functions which can be run in a special context when used with new.
Also, at some level it may be viewed that there needs to be no difference in calling a constructor multiple times (you get back a new object - so what?) than calling a function multiple times (where one might get back the same value). Consider that the new object may be immutable and may have value equality with other objects.
That is, considering the following code, is there a constructor used?
5 4 vec2 "1" int 2 vec2 add puts
I made it up, but I hope it makes a point. There may or may not be a constructor or an external difference between a constructor and an ordinary function depending upon how the specific language views the role (or even need) of constructors.
Now, write the language specification as deemed fit and try to avoid leaking implementation details.
Constructor is a constructor.
It may be like a function(that returns value: the new object), procedure(routine, function with no return value, called on uninitialized object), it may be callable once or many times on an object (although it is arguable whever the object is of the same identity afterwards..), it may have a name or not or the name may be enforced to match the class, etc. The constructor may even "not exist" or be implicitly created by the compiler from various scattered initializers and code blocks, which otherwise would be expressions/routines/whatchamacallit.
It all depends on your language that you compile and on what do you mean by 'function', 'routine', or even 'parameters' (i.e. is 'this' a parameter?).
If you want to ask about such thing, first describe/define your language and all your terms that you want to use (what is a class? method? function? routine? parameter? constructor? ...) and then, well, most probably you will automatically deduce the answer matching your ontology.
A constructor is a function with special semantics (such that it is called in specific context - as part of object construction), but it is a function anyway - it can have parameters, it has usual flow of control, it can have local variables, etc. It is not better or worse than any other function. I'd say it is a routine.
From outside, a constructor can be seen as a class method, with an instance of that class as return value. Insofar, the claim that "it can only be used once per instance" does not hold water, since there is no instance yet when the constructor is used.
From inside, some special keywordish name like "this" is bound to the uninitialized instance.
Usually, there is some syntactic sugar, like a new keyword. Also, the compiler may help to make sure the instance is properly initialized.
It is special insofar as the functionality of creating a new object is nowhere else provided. But as far as its usage is concerned, a constructor is not (or at least should not be) different from any other class method that happens to return an instance of the class.
BTW, is "routine" an established term in OOP?
I think that a Routine is what is that can be called explicitly as and when required by the caller on a constructed object/class, while a constructor can be called a special type of routine that is called at runtime when the instance of the class is requested.
A constructor helps only in constructing and initializing the class
object and its variables.
It may or may not accept parameters, it can be overloaded with
different set of parameters
If the constructor has no parameters and also no code inside its code
block, you may want to omit it
Some languages automatically create a default parameter-less
constructor (like C#) if you do not provide your own constructor
A constructor can have an access modifier to restrict the creation
scope of the class
A constructor cannot have a return type because its constructing the
same class in which it is declared, and obviously there is no point
returning the same type (may be that's the reason some languages use same name for the constructor as the class name)
All the implementation rules for a constructor differ from language to language
Furthermore, the most important requirement of a well written constructor is that after it is executed it should leave the class object in a valid state
A constructor (as in the name) is only executed by the compiler when you create a new instance of that class.
The general idea is this: You put some set of operations which should be executed during the startup and that is what is done on the constructor. So this implies, you cannot call a constructor just like the other methods of your class.
I have a strong feeling that I do not know what pattern or particular language technique use in this situation.
So, the question itself is how to manage the growing parameter list in class hierarchy in language that has OOP support? I mean if for root class in the hierarchy you have, let's say 3 or 4 parameters, then in it's derived class you need to call base constructor and pass additional parameters for derived part of the object, and so forth... Parameter lists become enormous even if you have depth of inheritance more than two.
I`m pretty sure that many of SOwers faced this problem. And I am interested in ways how to solve it. Many thanks in advance.
Constructors with long parameter lists is an indication that your class is trying to do too much. One approach to resolving that problem is to break it apart, and use a "coordinator" class to manage the pieces. Subclasses that have constructor parameter lists that differ significantly from their superclass is another example of a class doing too much. If a subclass truly is-a superclass, then it shouldn't require significantly more data to do its job.
That said, there are occasional cases where a class needs to work on a large number of related objects. In this situation, I would create a new object to hold the related parameters.
Alternatives:
Use setter injection instead of constructor injection
Encapsulate the parameters in a separate container class, and pass that between constructors instead.
Don't use constructors to initialize the whole object at once. Only have it initialize those things which (1) are absolutely required for the existence of the object and (2) which must be done immediately at its creation. This will dramatically reduce the number of parameters you have to pass (likely to zero).
For a typical hierarchy like SalariedEmployee >> Employee >> Person you will have getters and setters to retrieve and change the various properties of the object.
Seeing the code would help me suggest a solution..
However long parameter lists are a code-smell, so I'd take a careful look at the design which requires this. The suggested refactorings to counter this are
Introduce Parameter Object
Preserve Whole Object
However if you find that you absolutely need this and a long inheritance chain, consider using a hash / property bag like object as the sole parameter
public MyClass(PropertyBag configSettings)
{
// each class extracts properties it needs and applies them
m_Setting1 = configSettings["Setting1"];
}
Possibilities:
Perhaps your class(es) are doing too much if they require so much state to be provided up-front? Aim to adhere to the Single Responsibility Principle.
Perhaps some of these parameters should logically exist in a value object of their own that is itself passed in as a parameter?
For classes whose construction really is complex, consider using the builder or factory pattern to instantiate these objects in a readable way - unlike method names, constructor parameters lack the ability to self document.
Another tip: Keep your class hierarchy shallow and prefer composition to inheritence. That way your constructor parameter list will remain short.