[Tutor] What's the correct way to define/access methods of a member variable in a class pointing to an object?

Alan Gauld alan.gauld at yahoo.co.uk
Sat Sep 3 09:51:22 EDT 2016


On 03/09/16 06:55, Sharad Singla wrote:

> What's the correct way to define/access methods of a member variable in a
> class pointing to an object?

Steven has already given you a long and comprehensive
answer based on pragmatic python programming. But since
you use the term "correct" I'll give you an alternative
view based on generic/theoretical OOP practice. The caveat
is that theoretical best practice does not always transfer
to the real world and you must compromise. Just ensure you
compromise in the full knowledge that it is a compromise...

The first thing to do is point out that what you
are asking about is the Law of Demeter on OOP.
See Wikipedia for a full description. In essence
it says that the user of an object should not
directly access that object's internal attributes/state.
So ideally you only access foo via a call to a method of
Bar.

BUT... that does not mean you should expose all
of foo's interface as methods of Bar. After all Bar
should only have an instance of Foo to support its
own behaviour. In other words whatever methods you
call on Bar may manipulate Foo *behind the scenes*.
(If Foo is not being used by Foo's methods then what
is it doing in Bar at all?!)

So if you really want to change some aspect of
Bar's Foo instance then it should only be happening
as a result of you doing something to your Bar instance.

If you really, really need to modify the Foo instance
directly (and this should be fairly rare) the "correct"
OOP way to do that is for Bar to provide a getFoo()
accessor method and for you to fetch the Foo instance
and then manipulate it directly

b = Bar()
f = b.getFoo()
f.someMethod()
f.someAttribute = 42
# etc...
b.setFoo(f)   # put it back when you are done.

This then keeps Bar's use of foo hidden (you don't know
if Bar is returning a reference to its internal Foo
or creating a copy for you to play with.) In python
we tend to use direct access rather than getFoo/setFoo.
We'd just say b.foo, but that means if Bar wants to
return a copy of Foo then it needs to implement foo
as a property.

So to summarise, the Law of Demeter states that you
should provide foo access via Bar's interface but the
expectation is that you only create operations(methods)
on Bar that modify Foo as a part of that operation,
not that you simply expose all of Foo via Bar.

One huge exception to all of this is where you create
Bar explicitly as a manager of Foo objects and its
role is only to provide access to Foos (an example
might be an object pool in a server application).
But in that case there probably should be get/set
methods which will do some sanity checking before
handing over a Foo to you to play with, or storing
a foo that you have been messing about with.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list