Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we pass objects rather than object members to functions?

I have a method FOO() in class A that takes as its arguments input from data members of class B among other things (let's say they are two floats and one int). The way I understand this, it is generally better to implement this with something like:

A->FOO1(B, other_data_x)

rather than

A->FOO2(B.member1, B.member2, B.member3, other_data_x).

I gather one, but not the only, advantage of this is that it leaves the detail of which members of B to access up to FOO1() and so helps hide implementation details.

But what I wonder about is whether this actually introduces additional coupling between classes A and B. Class A in the former case has to know class B exists (via something like include class_B_header.h), and if the members of B change or are moved to a different class or class B is eliminated altogether, you have to modify A and FOO1() accordingly. By contrast, in the latter approach, FOO2() doesn't care whether class B exists, in fact all it cares about is that it is supplied with two floats (which in this case consist of B.member1 and B.member2) and an int (B.member3). There is, to be sure, coupling in the latter example as well, but this coupling is handled by wherever FOO2() gets called or whatever class happens to be calling FOO2(), rather than in the definition of A or B.

I guess a second part of this question is, is there a good way to decouple A and B further when we want to implement a solution like FOO1()?

like image 571
user1790399 Avatar asked May 23 '13 14:05

user1790399


2 Answers

But what I wonder about is whether this actually introduces additional coupling between class A and B.

Yes, it does. A and B are now tightly coupled.

You seem to be under the impression that it is generally accepted that one should pass objects rather than members of those objects. I'm not sure how you got this impression, but this is not the case. Whether you should send an object or members of that object depends entirely on what you're trying to do.

In some cases it is necessary and desirable to have a tightly coupled dependency between two entities, and in other cases it is not. If there is a general rule of thumb that applies here, I would say if anything it is the opposite of what you have suggested:

Eliminate dependencies wherever possible, but nowhere else.

like image 84
John Dibling Avatar answered Sep 30 '22 16:09

John Dibling


There's not really one that's universally right, and another that's universally wrong. It's basically a question of which reflects your real intent better (which is impossible to guess with metasyntactic variables).

For example, if I've written a "read_person_data" function, it should probably take some sort of "person" object as the target for the data it's going to read.

If, on the other hand, I have a "read two strings and an int" function, it should probably take two strings and an int, even if (for example) I happen to be using it to read a first and last name, and employee number (i.e., at least part of a person's data).

Two basic points though: first, a function like the former that does something meaningful and logical is usually preferable to one like the latter that's little more than an arbitrary collection of actions that happen to occur together.

Second, if you have a situation like that, it becomes open to question whether the function in question shouldn't be (at least logically) part of your A instead of being something separate that operates on an A. That's not certain by any means, but you may simply be looking at poor segmentation between the classes in question.

like image 29
Jerry Coffin Avatar answered Sep 30 '22 16:09

Jerry Coffin