Passing arguments between classes - use public properties or pass a properties class as argument?
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:
- Having Abc class make public some properties that would allow draw() to make its decisions.
- 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.
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.
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.
Go with approach #2, but without the object. Just pass the parameters to Draw
directly.
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.
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".
精彩评论