PetaMem has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I have stumbled about an implementation issue, which I´m not that sure how to solve. It´s not about programming, but rather design - more specifically nomenclature of object methods.

I have several objects which represent a more or less granular view of some world facts. Lets keep it simple: There is an object class called Entry it has semantic knowledge about a word/phrase. Now I would like to have a method that does the semantic consistency check. This is no problem, but the consistency check is only in the scope as far as the Entry data structure can see - that is, within its own data. So far so good.

Then there is a superposed structure - Dictionary that also has to do semantic checks, but the scope is wider, the checks are touching virtually all Entry-Objects (that are part of the Dictionary).

And last there should be a consistency-check routine, that is looking at several dictionaries simultaneously. Now my problem/ question:

In my first approach I was tempted to call all of these methods semcheck and there will be of course no nameclashes as all semchecks are in separate Namespaces, but is it really a good idea to have them all have the same name? FOrmally the answer would be yes, as they all serve the same purpose within their own semantics. But practically I have serious doubts:

Just because of readability of the code. Objects of the various Classes may exist in parallel and the situation can arise, where in the global function (no method) named semcheck you have a call $e->semcheck; folowed by $d->semcheck probably folowed by a recursive call to &semcheck;

What say you? Should I avoid calling them the same (and thus circumventing what OO would like to abstract), or should I have faith in readability of good OO code? What is your experience?

Thank you for your opinions and suggestions

Richard

Replies are listed 'Best First'.
Re: Question to OO Masters (about Style)
by Masem (Monsignor) on Nov 04, 2001 at 18:36 UTC
    IMO, I think keeping the same name for that function in the different namespaces is not only reasonable, it's preferred. The same 'check' is being done on all 3 object types, so there's no reason to pretend they are different. And from the standpoint of the Dictionary and higher grouping functions, your OOP should be hiding the recursive nature of that function call to the end developer. Typically in other OOP languages, when classes have a similar behaving non-inherited method, the designers typically have the method name the same as to avoid extra terminology in the API.

    Now, however, I would try to make sure that the variable you use are more descriptive than just $d or $e, if this code will be seen by others, unless no abiguity can be inferred. This way, it's understood that you're doing a consistancy check on a dictionary object or a entry object, as opposed to figuring out what each is.

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

      Hello,

      Thanks for all your responses. To clarify things a bit: I of course use more verbose variable names than $d or $e. (not to speak of $a and $b :-))

      My worries were not so much about the readability for an "end developer" as was stated here, but about the readability of the code by myself. As this is a long term project, I WILL have to dig through the code perhaps in 2 years. And now we all know, that perl has a little bit the reputation, that one cannot read his own code after a while.

      Entry is not derived from Dictionary (or vice versa), they are completedly separated classes, DIctionary is just some kind of container for (many) Entries.

      Yes, this is real-world scenario, no academic talk. 11 Languages (dictionaries) take 800MB of RAM. Long live Perls Memory Management. :-))

      And this beast knows already the difference between a Monkey and a Car.

      Bye
      Richard

(jeffa) Flyweight Pattern
by jeffa (Bishop) on Nov 04, 2001 at 20:33 UTC
    Just to add confusion >:) - another possible approach might be to have a Semantic Checking base class that contains any common code between the way an Entry and a Dictionary checks for valid semantics. Maybe Entry will use this class directly, while Dictionary will use a specialized sub-class.

    As Masem said, there is nothing wrong with different classes sharing the same method names. That's usually good design.

    I recommend designing the three different Semantic classes, if you find any substantial amount of commonality, look into interitance. It seems to me that the Entry checker is the simple one, Dictionary checker does a bit more work, and then your last checker does even more work. This might be a good candidate for aggregation, where the Dictionary checker passes off some of it's responsibilty to the Entry checker, maybe. TIMTOWTDI, especially in OO design.

    I heard Flyweight pattern mentioned in the chatter yesterday. Here is a brief explanation taken from Design Patterns (the GoF book):

      A flyweight is a shared object that can be used in multiple contexts simultaneously... Flyweights model comcepts or entities that are normally too plentiful to represent with objects. For example, a document editor can create a flyweight for each letter of the alphabet. Each flyweight stores a character code, but its coordinate position in the document and its typographic style can be determined from the text layout algorithms and formatting commands...

    In other words, the character code being stored in a given flyweight is called intrinsic state, it is information independent of the flyweights context - whereas the info about the character's position and font are passed to the flyweight object by the client when it need them. This information depends upon the flyweight's context - this is known as extrinsic state.

    So, do you need to implement the Flyweight pattern on this problem? Probably not - the Flyweight would only be good if you had started with it, and had more than 3 objects in question. So at this point, i recommend going ahead with your original idea, and call each method from Entry, Dictionary, etc. the same - semcheck() works for me. ;)

    Every problem is different, and as such, each implementation will have subtle differences. Does code A belong in object foo or bar. Try both and see which is the most flexible, and which is simplest.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    F--F--F--F--F--F--F--F--
    (the triplet paradiddle)
    
Re: Question to OO Masters (about Style)
by chromatic (Archbishop) on Nov 05, 2001 at 00:50 UTC
    It seems like part of your naming confusion may be due to some design confusion. An alternate approach to object decomposition is to look for verbs, not nouns. That is, if you come to see encapsulation as hiding behavior as well as data, you'll find it easier to pick out objects.

    Figure out what you need to do, and write objects to do those things. The actual data will tend to fall out from there.

    Looking at the problem very quickly, I'd probably make the Entries do their semantic checks. If it's necessary to do a global check in a Dictionary, I'd probably write something like check_all() that just iterates over the collection.

    If you need similar behaviors that can apply to an Entry or Entries, it may be worth breaking those checks out into separate classes. It's hard to say, but I'd revisit the design. It may be more flexible elsewise.

Re: Question to OO Masters (about Style)
by Biker (Priest) on Nov 04, 2001 at 21:11 UTC

    I think Masem is absolutely right. In your example, which may or may not be realistic, you have a different problem than what you're asking about.

    If you spend energy (well done) to figure out the best naming conventions for your methods in different classes, then you should probably spend a minute or two thinking of the naming of your variables in your non-OO sub.

    $c and $d may be commonly used (and make sense) in a small Perl script. But in any bigger script, including the design of several class modules, these variables should probably be named in a more descriptive way.

    $d->semcheck can be made a lot more descriptive by using $dictionary->semcheck().

    $dictionary->semcheck() and $entry->semcheck() already reads out more clearly.

    f--k the world!!!!
    /dev/world has reached maximal mount count, check forced.

Re: Question to OO Masters (about Style)
by Fastolfe (Vicar) on Nov 04, 2001 at 21:05 UTC
    What do you mean by "superposed"? Do you mean that Entry is descended from Dictionary (or vice-versa)? Is that necessary or desired?

    What you're describing, though, as other posters mentioned, is perfectly fine from a design point of view.

    package Dictionary; ... sub check { my $self = shift; my $error; foreach (@{$self->{children}}) { $error++, last unless $_->check(@_) } return !$error; } package Entry; ... sub check { my $self = shift; return 1 if $self->{value} > 0; # or whatever return; }
    If one is a descendent of the other, though, that makes things a little weirder but still workable.