views:

54

answers:

4

UPDATE: My original question wasn't quite clear. I'm looking for the name of the principle that code like the example below violates.

(I've updated the code example to better resemble the scenario I'm talking about. The original code example I included can be found at the bottom. This was a poorly chosen example because it illustrated a hierarchical structure that actually should provide access to sub-members at an arbitrary "depth" level and furthermore had almost nothing to do with composition, which is what I meant to be asking about.)


I'm pretty sure there's a term for this and I'm just having trouble thinking of it.

Example of bad code:

public interface IJumper
{
    void Jump();
}

public class Creature
{
    public IJumper Jumper;
}

var c = new Creature();
c.Jumper.Jump();

Example of better code:

public class Creature : IJumper
{
    private IJumper _jumper;

    public void Jump()
    {
        _jumper.Jump();
    }
}

var c = new Creature();
c.Jump();

I'm pretty sure I've heard this (exposing a member object directly so that all its properties/methods are publicly accessible) described as a bad thing due to [insert name of principle here]. What is the word I'm looking for?

(Note that I'm not asking why this is/isn't a bad thing; I'm just looking for the term, which for the life of me I can't remember.)


Original (bad) code example:

public class Person
{
    public Person Child;
    // ...
}

Person p = new Person("Philip J. Fry");

// what is the term for this?
Person greatGrandchild = p.Child.Child.Child;
+2  A: 

It seems to qualify for several: Message Chains, Middle Man, Indecent Exposure, and maybe Feature Envy. http://www.codinghorror.com/blog/2006/05/code-smells.html

If that pattern is used frequently, you probably need a property called GreatGrandChild that looks it up internally.

Matt
Maybe something like this would be more appropriate:`Person greatGrandchild = p.Children["Jim"].Children["Tom"].Children["Rick"];`
ChaosPandion
@ChaosPandion: Yes, a class of the sort I posted would be pretty horribly designed (one child per person?); it was just for the sake of offering an example.
Dan Tao
@Matt: All great answers. Really I was dumb to have included a bad example in my original question, though; the principle I was *really* looking for was the Law of Demeter. My fault for the bad code example.
Dan Tao
+2  A: 

It's called method chaining (well... in this example it could be property chaining). It's strongly linked with fulent interface.

On of these should be the term you're looking for.

Crozin
@Crozin: Good answers. This was my fault for including a bad code example in my initial question.
Dan Tao
A: 

Violating encapsulation?

mkarasek
+3  A: 

Principles that may apply to this example are:

Information Hiding: Segregate design details in your code that are likely to change. Create a stable interface that protects the rest of the program from the implementation.

Encapsulation: Compartmentalize the elements of an abstraction that constitute its structure and behavior. Separate the contractual interface of an abstraction from its implementation. Use standard language mechanisms to bundle the data with the interface.

Note that the definitions of Information Hiding and Encapsulation I've given are quite similar, and various people have their own definitions of what these mean. I've pulled these from Wikipedia.

Interface Segregation Principle: The dependency of one class to another should depend on the smallest possible interface.

The question you must determine is whether writing your class this way, where Child itself is part of the interface, is a stable and minimal interface for clients to depend on. In most cases, OO programmers prefer to rely on an explicit set of methods as their interface instead of data members, so that they can change out the data members at will. Some will recommend that technique as a dictum. It may or may not apply in your case.

There's another principle that may or may not apply to your example:

Law of Demeter: Only talk to your immediate friends.

The Law of Demeter discourages deep access hierarchies like p.Child.Child.Child. Why? Because clients are then assuming deep structural knowledge about the objects they are talking to, and it increases coupling between the client and those objects. Having said this, I think there are plenty of examples in the world where this coupling is acceptable; you'd need to decide whether it applies in your case as well.

EDIT: With your revised example, the Law of Demeter looks to me much closer to what you're looking for.

Owen S.
That's what I was looking for! The Law of Demeter. Thanks.
Dan Tao