5

I know there are plenty of articles and questions about MVC and best practices, but I can't find a simple example like this:

Lets say I have to develop a web application in PHP, I want to do it following the MVC pattern (without framework). The aplication should have a simple CRUD of books.

From the controller I want to get all the books in my store (that are persisted in a database).

How the model should be?

Something like this:

class Book { private $title; private $author; public function __construct($title, $author) { $this->title = $title; $this->author = $author; } public function getTitle() { return $this->title; } public function setTitle($title) { $this->title = $title; return this; } . . . class BooksService{ public getBooks(){ //get data from database and return it //by the way, what I return here, should by an array of Books objects? } public getOneBook($title){ //get data from database and store it into $the_title, $the_autor $the_book = new Book($the_title, $the_autor); return $the_book; } . . . 

So I call it(from the controller) like that:

$book_service = new BooksService(); $all_books = $book_service->getBooks(); $one_book = $book_service->getOneBook('title'); 

Or maybe should be better have everything in the Books class, something like this:

class Book { private $title; private $author; //I set default arguments in order to create an 'empty book'... public function __construct($title = null, $author = null) { $this->title = $title; $this->author = $author; } public function getTitle() { return $this->title; } public function setTitle($title) { $this->title = $title; return this; } public getBooks(){ //get data from database and return it //and hare, what I should return? an Array? } public getOneBook($title){ //get data from database and store it into $the_title, $the_autor $the_book = new Book($the_title, $the_autor); return $the_book; } . . . 

So I call it(from the controller) like that:

$book_obj = new Book(); $all_books = $book_obj->getBooks(); $one_book = $book_obj->getOneBook('title'); 

Or maybe I'm totally wrong and should by in a very different way?

Thank you!

2 Answers 2

3

Looking at your two solutions, ask yourself - what happens if you want to start adding more and more types of lookup (by Author, Title, Date). Should they belong in the book model? (a model being a representation of a Book). No would be my answer.

The Book class should be a representation of your Book (Title, Number of pages, Text, etc) - stored in the database in this case.

In my opinion your first approach is your best approach - separate your business logic of looking up a Book into a separate object (following your convention I would suggest something like BookLookupService), which is responsible for looking up a book instance, for example:

interface IBookLookupService { findBookByTitle($bookTitle); findBooksByAuthor($authorName); getAllBooks(); } 
Sign up to request clarification or add additional context in comments.

2 Comments

What's difference between implement IBookLookupService and using BookService class? The author already separated two class, one is stand for book is Book, and one handle business logic is BookService
@TomSawyer Because you're not referencing a concrete implementation, meaning you can easily replace your implementation to IBookLookupService for a mock (for instance). You should always aim to program towards an interface, not an implementation.
3

Both ways are correct and correspond to two different patterns.

Your first idea could be associated with the Data mapper pattern. In this case your book class doesn't have to know anything about the database, and let another class worrying about database operations. This is the pattern use by projects like Doctrine2 or Hibernate (I think)

The second one is known as Active record pattern where you keep everything in a single class and your book object has to manage its own persistence. This is the pattern used by Ruby on Rails.

The first approach generally give you more flexibility but second one may look more intuitive and easy to use.

Some informations:

http://culttt.com/2014/06/18/whats-difference-active-record-data-mapper/

1 Comment

In the second way: storing method like getBooks in Book object will cause the memory or expose the unnecessary method on the public? Image you have a bookArray that contains 100 books and each one will have the same getBooks , getOneBook methods

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.