views:

102

answers:

5

So let's assume I have a class named ABC that will have a list of Point objects.

I need to make some drawing logic with them. Each one of those Point objects will have a Draw() method that will be called by the ABC class.

The Draw() method code will need info from ABC class.

I can only see two ways to make them have this info:

  1. Having Abc class make public some properties that would allow draw() to make its decisions.
  2. Having Abc class pass to draw() a class full of properties.

The properties in both cases would be the same, my question is what is preferred in this case. Maybe the second approach is more flexible? Maybe not? I don't see here a clear winner, but that sure has more to do with my inexperience than any other thing.

If there are other good approaches, feel free to share them.

Here are both cases:

class Abc1 {
    public property a;
    public property b;
    public property c;
    ...
    public property z;

    public void method1();
    ...
    public void methodn();
}

and here is approach 2:

class Abc2 {
    //here we make take down all properties

    public void method1();
    ...
    public void methodn();
}

class Abc2MethodArgs {
    //and we put them here. this class will be passed as argument to
    //Point's draw() method!
    public property a;
    public property b;
    public property c;
    ...
    public property z;
}

Also, if there are any "formal" names for these two approaches, I'd like to know them so I can better choose the tags/thread name, so it's more useful for searching purposes. That or feel free to edit them.

+1  A: 

Go with approach #2, but without the object. Just pass the parameters to Draw directly.

Matthew Ferreira
Passing the parameters directly seems odd. If later I want to add more parameters I'm in a big problem..
devoured elysium
So that gets me a down vote? Remind not to try to help you ever again.
Matthew Ferreira
Your post is not only kind of useless but wrong. Passing properties directly in methods is not desired in well behaved OO programming. That's why you have in forms event programming EventArgs instead of passing the values themselves directly.
devoured elysium
Anyway if it rep bothers you that much I can take the down vote away. But just if it makes you happy :) (you'll have to edit your post though, otherwise it won't allow me to change the vote)
devoured elysium
You're not calling an event in your case though. Consider all the various drawing methods in the `Graphics` class. Are you saying that `Graphics` was designed wrong? It fairly straightforward to use.
Matthew Ferreira
devoured elysium
+1, as I realized that I am essentially recommending the same. Why is it more OO to depend on a set of properties in a class than to depend on a series of parameters to a method? If OO is about decoupling, it is not.
tucuxi
The problem is what happens if later you need to add new properties. If later I decide to add a new property to my ABC or Abc2MethodsArg class, I can add them, and that won't break any existing code. Everything will compile with no problems. If in the other hand I have to change Point's draw() signature to accomodate for that new property, I'll have to make changes both on ABC and Point classes, even if I don't even want to use that new property. Of course that if I want to use it, I will have to make changes in the draw() logic too.Or maybe I'm missing something in what your implementation is
devoured elysium
@devoured: in your original question, you ask about flexibility; you did not specify that you were worried about adding arguments to Draw instead of being able to (say) use Points from outside ABC.
tucuxi
+1  A: 

Since the Point class and ABC appear to have to mediate between themselves as to what to draw, why not call the draw() method on the Point, passing the actual ABC object as an argument. The ABC object can provide accessor methods (don't expose those properties!) and the point class (or subclass implementations) can decide what to call back on ABC for.

Brian Agnew
What would be the difference between providing accessor methods and exposing properties? You mean only letting the client of the class read the data, instead of letting it set it too? Or you mean something like only letting the client get "interfaces" instead of actual data?
devoured elysium
It allows you to refactor the class whilst maintaining the same interface, to log access and/or otherwise manage the accessing of those properties.
Brian Agnew
+2  A: 

It will be more work to create and maintain a separate class to pass state between ABC and point, but it's worth doing if you want to decouple point from ABC.

The main question is, how much does decoupling them matter to you, if it matters at all? If it makes sense in your domain for point instances to know about abc instances, it probably isn't worth creating the parameter class and you should just go with option 1.

Jeff Sternal
I agree - if Points know about the properties in ABCs, then there is little decoupling to be achieved by putting those properties in a separate class.
tucuxi
Right now Points don't know about ABCs properties. I would have either public properties in ABC or just public properties on AbcMethodArg, not on both(or I didn't understand what you meant with it).
devoured elysium
+2  A: 

The best approach depends on the nature of the information ABC needs to provide to the Point instances, the nature of the relationship between these classes, and the "expected" future for them. In other words there are a lot of qualitative factors.

If you do go with passing the Point an ABC instance, don't - rather, work out an appropriate abstraction for whatever it is Point needs from ABC, and encapsulate that in an interface. In static terms this is similar to simply creating a new class to encapsulate the information, but dynamically quite different.

The reason you shouldn't simply pass an instance of ABC is that it creates a circular dependency. Without going into too much detail, this should generally be regarded as a Very Bad Thing and avoided unless absolutely necessary.

And, at a more abstract level, it will make more sense and enable logical changes later if you identify the reason for this apparent circular dependency and factor that out - ie, create an interface to represent this 'data source for Points' role which ABC must fulfil. This role is distinct from the 'container for Points' role and that should be reflected in your design.

You could also pass the parameters to the draw() method - again this may be good or bad depending on a heap of factors. It's certainly not a Very Bad Thing, as long as you've thought about the implications.

Steven Mackenzie
You made a couple of very interesting points. First of all, could you please elaborate on why that circular dependency is a bad thing? In this case, all that ABC is doing is doing a foreach on each of its Point objects(that are stored in a ArrayList as a private instance variable). The logic itself is all in the Point object. Also, you say that "In static terms this is similar to simply creating a new class to encapsulate the information, but dynamically quite different." Why is that so? Thanks!
devoured elysium
Good point on passing an 'interface to ABC' to the Points instead of a plain ABC.
tucuxi
Here's a decent discussion on circular dependencies: http://stackoverflow.com/questions/1356304/are-circular-class-dependencies-bad-from-a-coding-style-point-of-view Regarding the static-dynamic distinction - an interface to encapsulate access to the information in ABC required by Point will statically (ie, think class diagram) be very similar to the MethodArgs class you mentioned -- but the dynamic behaviour (think interaction diagrams) will be very different. In particular the information will not be copied from an ABC instance to a MethodArgs instance.
Steven Mackenzie
+1  A: 

You may want to consider reversing the dependencies. Instead of Points accessing properties from ABC, have ABC set properties on the points when (or just before) calling "draw()" on each of them. Something similar to the Flyweight pattern used when rendering cells in Swing's JTables (see javadoc). You may also consider decoupling Point (data model) from PointDrawer (reusable rendering code). That way your Points will not depend on all those properties, only your PointDrawers will.

And yes, it is OO programming even if you explicitly pass in all parameters to each Point at drawing time - that way, Points have no dependency at all on either ABC or on ABC's would-be "parameter-passing class".

tucuxi
About reversing the dependencies, it seems first of all a very interesting idea (I hadn't thought of that!). But now that I think of it, isn't that leading to the same as having a ABCMethodArgs class? What would be the advantage here? The points here are already what you would call PointDrawers.
devoured elysium
In general, making classes depend on each other is bad (as you are making it difficult to reuse them or change them independently of each other). If you plan to change the arguments to Draw, then the approach suggested by Steven Mackenzie is better than this one. I still doubt that the Properties object is justified, as it is equivalent to, and more complicated than, the interface that Steven is suggesting.
tucuxi