Best Practice to Avoid “Playing Telephone” with Constructor Arguments

  softwareengineering

I find that the encapsulation required by OO has me frequently passing paramenters down the line from parent to child to great grandchild to second grand nephew once removed (not actually that bad). But inevitably in the process, and especially if graphics are involved there will be garbling the by the third iteration of someConstructor(int minX, int minY, int maxX, int maxY).

I found at least one question here suggesting that parameter objects are the solution. These seem to me more like a kludge designed to satisfy a low parameter count fetish than genuinely useful. Besides, in these scenarios, I am generally cutting the numbers into smaller pieces (of screen) with each step.

It occurs to me if these constructor calls are laid out line by line higher up the chain, I’d have easy comparisons. But this seems to lose all semblance of OOPiness. In my most recent adventure with find-the-transposed-measurements, I was drawing a music keyboard. I don’t want the main view to know or care what or exactly where the G# key is.

So, best practices? Please don’t say, go slower, be less sloppy.

5

To expand on @9000’s comment, I would use objects that provide more information and possibly error checking about your arguments. For example, in the following:

drawLine(100, 20, 300, 30);
drawLine(new Point(100, 20), new Point(300, 30));

The second is generally more readable. It can check errors (can coordinates be negative? can a rectangle have a negative width or height?) and provides an easier way to access helper methods (such as converting coordinate systems or affine transformations). Also, if there is a lot of data being passed around (such as a list of points for a polyline), you end up passing object references rather than the whole data structure.

5

I’m not entirely sure what your class hierarchy looks like, but I will give you my thoughts on object construction and how I have started designing my classes in projects I work on.

  • Inheritance or Composition: It sounds like you are assuming that because you are programming in an OO style, you must always use inheritance; this is just not true. It is up to you, the designer, to determine what solution best solves you problem. Below I’ll give you an example of composition instead of inheritance.

  • Parameter Objects (as you put it): When you design a class, you are modeling your data by how it is seen in your head; you are giving it a name and structure. A simple example would be a class called Point2D that would have an X and a Y property associated with that class. The good thing about creating this “parameter object” is now you can create functions or methods that operate on that object. I don’t create Point2D with a constructor, I make a second class called Point2DFactory with a static Create(x, y) method. This does 2 things for me, it keeps my Point2D class light weight and puts all the logic for creating a Point2D in one place. I can now compose a Point2D in anyway I wish and the Point2D is no longer responsible for both being a point and knowing how a point is created. It is not tied to some inheritance chain, it is the Point2DFactory’s job to worry about that.

  • Inversion of Control: If you need to encapsulate some over arching functionality into a single object that can be broken down into little bits of functionality, you can use an inversion of control framework to help you out. What it does is take all those “parameter objects” you have created (hopefully with abstract interfaces) and figures out how to build the object you require by injecting the functionality into it’s constructor.

If you are creating constructors that rely on some math to generate their parameters, consider creating a parameter object and a factory that creates it. Then you can make another factory that creates your desired object based on any input you wish. Can you tell I use the factory pattern a lot :P? I hope what I have said shows you that creating more objects isn’t a bad thing (OOP requires it :/) and if you can get each class/object to only have one responsibility, your overall code base will be extremely flexible and a pleasure to maintain.

EDIT in response to comment: Maybe I am not understanding exactly what you are asking. I thought your problem what nested constructors that have similar input names. What I was trying to get at is that, in general, a parent shouldn’t need to know how to instantiate its child objects. That makes your parent responsible for doing what ever it is the parent does AND for creating the child objects. If the parent’s soul purpose to is create the child objects, that is called a factory in design pattern terms. Instead of constructor chaining, pull that logic that instantiates child objects outside of the constructors. This giving you more flexible usability of the logic that creates child objects and better adherence to SOLID principles.

2

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT