Php – Reusable VS clean code – where’s the balance

clean codecode-qualitycode-reusecode-reviewsPHP

Let's say I have a data model for a blog posts and have two use-cases of that model – getting all blogposts and getting only blogposts which were written by specific author.

There are basically two ways how I can realize that.

1st model

class Articles {

    public function getPosts() {
        return $this->connection->find()
            ->sort(array('creation_time' => -1));
    }

    public function getPostsByAuthor( $authorUid ) {
        return $this->connection->find(array('author_uid' => $authorUid))
            ->sort(array('creation_time' => -1));
    }
}

1st usage (presenter/controller)

if ( $GET['author_uid'] ) {
    $posts = $articles->getPostsByAuthor($GET['author_uid']);
} else {
    $posts = $articles->getPosts();
}

2nd one

class Articles {

    public function getPosts( $authorUid = NULL ) {
        $query = array();

        if( $authorUid !== NULL ) {
            $query = array('author_uid' => $authorUid);
        }

        return $this->connection->find($query)
            ->sort(array('creation_time' => -1));
    }

}

2nd usage (presenter/controller)

$posts = $articles->getPosts( $_GET['author_uid'] );

To sum up (dis)advantages:

1) cleaner code

2) more reusable code

Which one do you think is better and why? Is there any kind of compromise between those two?

Best Answer

The trick is that you do not have to choose. One nice thing that many ORMs provide (for instance that of Django, Squeryl, SQLAlchemy and more) is composable queries. That is, you can not only query a table but query the results of another query. This is not as costly as it looks, as either the ORM or the DB query optimizer can reduce it to a combined SELECT under the hood.

So you would end up with something like (Django example)

class Article:
  @staticmethod
  def posts():
    return Article.objects.all()

  @staticmethod
  def author_posts(author):
    return Article.posts().filter(author=author)

There you have - two separate methods and no repetition. :-)

When you have to choose between clean and reusable, there is often a third option: a little more sophisticated but both clean and reusable.

(By the way, the static methods are there just to mimic your structure. Actually one would have instance methods on the Article manager class. I should also add that this is a trivial example, as the default manager - named Article.objects - already provides the all method to retrieve all results. But this is not the point - the point is that you have obtained a more specific result set by querying a larger result set.)

Related Topic