Page 3 of 7

Re: oop question

Posted: Tue May 19, 2009 8:27 pm
by John Cartwright
The argument that it is up to the coder to implement your code properly is (in my opinion) absolutely absurd. I surely would not want a colleague have to figure out themselves what is the "proper" way to use my code. Better yet, what about opensource code that will potentially be developed over a large userbase. I would pull my hair if everytime I opened up a new library I would have to read all the comments in the code to determine the interface, or if I have to verify the methods/properties given through autocompletion in my IDE are acceptable to use. The whole point of encapsulation is to define an explicit interface to the object.

To each his own I guess...

Re: oop question

Posted: Tue May 19, 2009 8:29 pm
by Christopher
Jenk wrote:No, I do not want to restrict others from accessing it. That's the point I've been making *all* along. The comments will describe the purpose of the member, it's constraints and functionality. That's it. It's the developer's judegment to use it or not. I'm not going to make his or her call for him by restricting access.
So given that logic I assume that you declare all variables in functions as global and never use constants. Because you don't want to restrict the developers access from anything.

The only think I can think is that because PHP4 did not restrict access (unlike all other OO languages) that you just got used to it...

Re: oop question

Posted: Tue May 19, 2009 11:42 pm
by McGruff
Access restrictions are not a real requirement. What failing test could be made to pass by adding a visibility keyword?

You do of course need to label methods in some way, ideally the simplest way possible. I've never yet found a reason to abandon undescores.

Visibility in PHP

Re: oop question

Posted: Wed May 20, 2009 12:26 am
by Christopher
McGruff wrote:Access restrictions are not a real requirement.
I think you are mixing the requirements for development a class with the requirements for using a class. I consider "can't screw things up completely" a requirement for using a class.
McGruff wrote:What failing test could be made to pass by adding a visibility keyword?
How about this failing test. The code isn't giving me any errors and I can't figure out why it's not working? (reenactment of actual DevNet question)

Code: Select all

$model = new MyModel(new PDO($myconfig));
$model->db = "I don't know what I am doing";
$this->assertEqual($model->find('foo'), array('foo', 'bar'));

Re: oop question

Posted: Wed May 20, 2009 1:06 am
by McGruff
arborint wrote:I think you are mixing the requirements for development a class with the requirements for using a class.
They are one and the same. TDD doesn't care about implementation. The task - in OOP generally not just TDD - is to create behaviours and attach them to interfaces.
I consider "can't screw things up completely" a requirement for using a class
People can always find ways to screw things up. All you can do is establish a reasonable standard. I feel there is a missing sense of perspective sometimes with ppp. For example, before leaving the house, you don't read through a ten-page checklist of everything that could possibly go wrong:

wallet - check
keys - check
shoelaces tied - check
flies zipped up - check
clean underwear - check
...
...

Although any single failure could indeed be disastrous, some things just don't need to be enforced.
arborint wrote:How about this failing test.
That's not a test (ie specification). Why would anyone want to define that as a behaviour?

The behaviours which you do define will not mention any implementation details. Thus it doesn't matter whether protected methods are marked "protected" or prefixed with an underscore, in the old way. The test will pass (or fail) just the same.

Re: oop question

Posted: Wed May 20, 2009 1:23 am
by Christopher
McGruff wrote:That's not a test (ie specification). Why would anyone want to define that as a behaviour?
That certainly is a test. Just because you don't know why someone would write it does make it not a test.
McGruff wrote:The behaviours which you do define will not mention any implementation details. Thus it doesn't matter whether protected methods are marked "protected" or prefixed with an underscore, in the old way. The test will pass (or fail) just the same.
OK, added an underscore ... junior programmer goes back to work ... Hey it still does not work!

Code: Select all

$model = new MyModel(new PDO($myconfig));
$model->_db = "I don't know what I am doing";
$this->assertEqual($model->find('foo'), array('foo', 'bar'));
Let's make it protected. Hey, now the test passes.

Code: Select all

$model = new MyModel(new PDO($myconfig));
#$model->_db = "I don't know what I am doing";     // had to comment out because it was giving an error (don't know why)
$this->assertEqual($model->find('foo'), array('foo', 'bar'));
I am really getting a forest for the trees feeling here...

Re: oop question

Posted: Wed May 20, 2009 2:34 am
by onion2k
Jenk wrote:"You should write code how it should be written now and worry about changing it later if it needs to change."

That's ironic. You're restricting code because you don't want others to access it. I'm just not restricting it. Which, of those two, is apprehensive of future use?
The restrictions I'm talking about are for current use. If users shouldn't be accessing things directly now then you should code to stop them. If that changes later then you should change the code to let them. Write code to the spec, not some mythic possible spec that might occur in the future.
Jenk wrote:It's not up to you to explain why their code is failing, if they are improperly using your library. It's up to them to use your library properly.
It is up to me though. I wrote the library. The example I gave would fail in the library. It'd be up to me to tell the other developer that the code has failed because they set a class variable to an invalid value. By not allowing public access to the variable that possibility goes away, it can't happen. That is better in my opinion because it saves me having to support my code when it's used incorrectly, and it saves the other developer time fixing a problem that shouldn't arise in the first place.
Jenk wrote:FWIW I'm not advocating the direct interaction of member variables, infact I don't think I ever access them outside of testing (and even then it's only when testing wrappers or such and I need to place a mock or stub.) but I just don't see any restriction necessary. Ever.
Do you think other developers should be accessing class variables directly? If not, why not stop them? The fact is, while you're leaving everything public, you are advocating that people directly interact with class variables. If you thought it was wrong to do that you'd make the variables private. That's what the directives are there for.

Re: oop question

Posted: Wed May 20, 2009 4:38 am
by Jenk
Heaven forbid colleagues would actually need to talk to each other.

Re: oop question

Posted: Wed May 20, 2009 4:53 am
by onion2k
Jenk wrote:Heaven forbid colleagues would actually need to talk to each other.
Communicating is ace if it's worthwhile and constructive, but if you're talking about a code failure that could have been avoided by using private variables rather than public you're wasting everyone's time. Why would you want to do that?

Re: oop question

Posted: Wed May 20, 2009 5:02 am
by Eran
It's not always colleagues either. You will not always be the one maintaining your code (even, more often than not). Why not make life easy on would-be maintainers and let the code guide them through your intentions? (without them having to read all your code and comments just to get it to work)

Re: oop question

Posted: Wed May 20, 2009 6:04 am
by Jenk
onion2k wrote:
Jenk wrote:Heaven forbid colleagues would actually need to talk to each other.
Communicating is ace if it's worthwhile and constructive, but if you're talking about a code failure that could have been avoided by using private variables rather than public you're wasting everyone's time. Why would you want to do that?
You mean wasting time by mis-using a library. The variable will be clear as to what it's purpose is, so why would they assign something to it that will break it?! :?:

To counter aborint's example earlier, as well:

Code: Select all

$model = new MyModel(new PDO($myconfig));
$model->_db = new MockDB();
$this->assertEqual($model->find('foo'), array('foo', 'bar'));
Hey, it passes!

Re: oop question

Posted: Wed May 20, 2009 6:07 am
by Jenk
pytrin wrote:It's not always colleagues either. You will not always be the one maintaining your code (even, more often than not). Why not make life easy on would-be maintainers and let the code guide them through your intentions? (without them having to read all your code and comments just to get it to work)
Descriptive naming will make it obvious enough, as will tests, as will the developers own intuition when they try it out and it breaks.

Re: oop question

Posted: Wed May 20, 2009 7:19 am
by Eran
What you think are descriptive and meaningful names might not be to someone else. Also, I'd rather use a method/property name to convey what it does rather than whats its scope is.

Re: oop question

Posted: Wed May 20, 2009 8:15 am
by Jenk
.. and from that name, the developer can see what it ... well, does. He or she can determine from what it does to what effects it will have.

Re: oop question

Posted: Wed May 20, 2009 8:30 am
by McGruff
arborint wrote:That certainly is a test. Just because you don't know why someone would write it does make it not a test.
Er, sorry it isn't. In test driven design "tests" aren't really "tests". Primarily they are specifications (a point which Behaviour Driven Design tries to emphasise). You describe an expected behaviour, one piece at a time, and then you write the minimum code to make the "test" pass. Your test doesn't make any sense. It doesn't describe a desired behaviour.

"Minimum code" is the key point. You write the simplest thing to make a test pass. That's a crucial part of the process which stops false requirements - such as access restriction - slipping into the code. Non non-public methods are never called in tests and so visibility keywords have no effect on making the test pass. That ought to tell you something.

In years of programming with php4 I never once encountered a problem with this. Given that methods are labelled in some way, access restriction is an entirely imaginary problem. When you visit friends, how often do you try to climb in the window rather than ring the doorbell? When you are hungry and need energy, would you stick your fingers in a light socket or would you eat a pie? Just doesn't happen. Of course it could but it won't.

Programming is the art of expressing complex ideas as simply as you possibly can. False requirements must be ruthlessly exposed and unceremoniously dumped in the bin. We've got plenty real problems to wrestle with without inventing new ones.