GordonM
GordonM

Reputation: 31730

Interfacing with internal objects

I'm working on a case logging system. Each case can have comments attached, so I'm going to create a Case class and a Comment class and embed a Comment object in the Case class.

I'm thinking about how to provide the interface to the embedded Comment object. I could make it a public member and have the programmer access it directly, ($case -> comment -> addComment()), or make it private and put methods in the Case class to provide access to the comments through the Comment object (public function addComment () { return ($this -> comment -> addComment ()); }).

Thinking about it, the latter style would mean that the Case object becomes dependant on the Comment object. However, in the former case, the programmer may be able to do things like make the comments property of the Case object reference comments that don't belong to the case, or even to items that aren't comment objects!

Of the two approaches, which is considered to be the best practice?

Upvotes: 0

Views: 62

Answers (2)

Rene Terstegen
Rene Terstegen

Reputation: 8046

I don´t exactly understand what you mean, but...

I think you need something like this:

class Case {
    private $comment;

    public function getComment() {
        // Add some checks if necessary
        ...
        return $this->comment;
    }

    public function addComment(Comment $comment) {
        // Add some checks if necessary
        ...           
        $this->comment = $comment;
    }
}

You can also choose to make your $comment propery protected. This is especially useful if you want to extend the object.

Always make extensive use of encapsulation, it is one of the biggest advantages of OOP. It is always wise to make a class property protected or private. Without it you can't force checks on it when you set the properties. Keep in mind if you make a property public, every class can access and modify it without any checks. Think about the possible consequences of that!

$comment isn't a primitive type, its a reference to an instance of a comment clas

Good luck!

@Gordon: Doesn't matter. Even if it is a instance of a Comment and you make it public, you can still do so something like:

// $Case is a Case object, doh ;)...
$Case->comment = "Just a string value";

And suddenly your comment is a primitive type while you expect an instance of a Comment class... This can give you several errors. If you make it a protected or private property the line of code is just not possible outside of the class. Then you're forced to use a setter for it like:

public function setComment(Comment $comment) {
    ...
}

Your function expects a Comment and will throw an error if something else is given. This will ensure your object is consistent.

@Gordon: It is not a Comment class method you're building in your Case class. The methods described above are only needed for your Case class. The only thing they do is getting the Comment object that belongs to the Case class and Setting the Comment object that belongs to the Case class. Once you succesfully retrieved the Comment object with the getter, you can fire all public methods defined in your Comment class. So it does nothing with the Comment object itself.

Your Comment is still completely independent. The relationship between these objects is (most likely) saved in the table of the Case object. Your Case class is the only class that knows about the relationship. So you can still re-use your Comment class for other purposes.

Your Case class needs to know your Comment class in some way and this is the way to go!

BTW, consider a many-to-many relationship. I assume a Case can have more then one Comment.

Good luck!

Upvotes: 1

Dan Grossman
Dan Grossman

Reputation: 52372

The Case class should have its own methods to add/remove comments. This lets you change how comments are implemented in the future. You can have these methods simply wrap calls to your Comment class now but change it totally in the future.

Upvotes: 1

Related Questions