PHP OOP设计结构

And*_*ndy 5 php oop

我的问题适用于我为了更好地理解如何使用OOP而编写的这三个示例类.

class Book {
    //not using getters/setters to save some space
    public $name;
    public $numreads;
}

class BookFactory {
    private $db;
    public function __construct(Database $db) {
        $this->db = $db;
    }
    public function getBook($id) {
        $book = new Book();

        $book->name = $db->query("SELECT name FROM books...");

        $booknumreads = new BookNumRead($this->db, $book);
        $book->numreads = $booknumreads->getFromLocal() + $booknumreads->getFromAnotherSource();

        return $book;
    }
}

class BookNumRead {
    private $db;
    private $book;
    public function __construct(Database $db, Book $book) {
        $this->db = $db;
        $this->book = $book;
    }

    public function getFromLocal()
    {
        return $this->db->query("SELECT COUNT ... WHERE name = $book->name");
    }

    public function getFromAnotherSource()
    {
        return API::getNumReadsOfABook($book->name);
    }

    //or just stick with this method in this class
    public function getNumReadsOfBook($name)
    {
        return (
                $this->db->query("SELECT COUNT ... WHERE name = $name")
                +
                API::getNumReadsOfABook($name)
        );
    }
}

//get number of reads of a book
$db = new Database();
$bookfactory = new BookFactory($db);
$book = $bookfactory->getBook(123);
echo $book->getNumReads();
Run Code Online (Sandbox Code Playgroud)
  1. 首先,这是一个很好的OOP approch吗?

  2. 这些课程完全不同.域与值对象?例如,我的应用程序中可以包含所需数量的Book对象.然而,BookFactory就像我的应用程序中的服务,在我的应用程序中只需要一个,但我可能需要在我的应用程序中的许多其他地方使用此类,我应该将它作为ServiceLocator/ServiceContainer中的对象吗?

  3. BookNumRead类也可以放在ServiceLocator/ServiceContainer中,并且在没有注入Book对象的情况下由getNumReadsOfBook()方法使用,但这感觉就像过程编程一样?或者,如上例所示,由BookFactory :: getBook()进行推理,但是我需要将一个数据库(一个BookFactory注入)和一个Book传递给它,这感觉有点乱,请注意它可能需要其他"服务"类,例如记录器.这里的最佳做法是什么?

Jvd*_*erg 1

我认为您应该将数据库内容与模型/服务更多地分开。对数据库内容使用适配器模式并在单独的类中处理所有 SQL。您可以使适配器实现 PDO、MySQLi 等。

从更高、更务实的角度思考模型和服务,并将实现细节隐藏在底层的通用类中。