所以基本上我正在从程序编码跳到OOP。 我正在尝试实现OOP的原则,但我有一种唠叨的感觉,我实际上只是用Objects编写程序样式。
所以说我有一个管道/椅子/打印机列表/无论如何,它们都在我的单表数据库中列为产品。我需要构建一个webapp,根据类型显示整个列表和项目,重点是“正确”使用OOP及其范例。
执行此操作是否有任何不妥之处:
CLass Show { public function showALL(){ $prep = "SELECT * FROM myProducts"; $q = $this->db-> prepare($prep); $q->execute(); while ($row = $q->fetch()) { echo "bla bla bla some arranged display".$row['something'] } }
然后简单地
$sth = new show();
$sth->showAll();
我还会实现更具体的显示方法,如:
showSpecificProduct($ id) - >(当用户说点击其中一个链接时,$ id将通过$ _GET传递,我们会分开基本上只包含的product.php文件
include('show.class.php');
$sth = new show();
$sth->showSpecificProduct($id);
showSpecificProduct()将执行select查询并输出html进行显示。
所以为了简短起见,我是不是很好,或者我只是用类和对象进行程序编码。如果我做错了,还有任何关于解决它的想法/提示等吗?
答案 0 :(得分:2)
更合适的是实施repository pattern。示例界面可能是
interface ProductRepository
{
public function find($id);
public function fetchAll();
}
然后,您将创建此接口的具体实现
class DbProductRepository implements ProductRepsoitory
{
private $db;
public function __construct(PDO $db)
{
$this->db = $db;
}
public function find($id)
{
// prepare execute SQL statement
// Fetch result
// return result
}
public function fetchAll()
{
// etc
}
}
直接从方法或函数echo
通常是一个坏主意。让你的方法返回适当的对象/数组/其他并消耗这些结果。
答案 1 :(得分:2)
除了@Phil和@Drew描述的模型实践之外,我还建议您将业务,数据和视图层分开。
我已经包含了一个非常简单的版本,需要在您的实现中进行扩展,但我们的想法是让您的Db选择与您的输出分开,几乎"加入"两者一起在控制器中。
class ProductController
{
public $view;
public function __construct() {
$this->view = new View;
}
public function indexAction() {
$model = new DbProductRepository;
$products = $model->fetchAll();
$this->view->products = $products;
$this->view->render('index', 'product');
}
}
class View
{
protected $_variables = array();
public function __get($name) {
return isset($this->_variables['get']) ? $this->_variables['get'] : null;
}
public function __set($name, $value) {
$this->_variables[$name] = $value;
}
public function render($action, $controller) {
require_once '/path/to/views/' . $controller . '/' . $action . '.php';
}
}
// in /path/to/views/product/index.php
foreach ($this->products as $product) {
echo "Product ID {$product['id']} - {$product['name']} - {$product['cost']}<br />\n";
}
答案 2 :(得分:1)
您在上面描述的场景似乎是MVC的合适人选。
在您的情况下,我会严格创建一个类来访问数据(选择产品类别或特定产品),然后使用不同的文件(您的视图)获取输出并显示它。
看起来像这样:
class Product_Model {
public function find($prodId) { ... }
public function fetchAll($category = '') { ... }
public function search($string) { ... }
}
然后你可以做的其他地方:
$products = new Product_Model();
$list = $products->fetchAll(37); // get all from category 37
// in true MVC, you would have a view that you would assign the list to
// $view->list = $list;
foreach($ilst as $product) {
echo "Product ID {$product['id']} - {$product['name']} - {$product['cost']}<br />\n";
}
MVC的基本原则是您拥有的模型类只是表示来自某些数据源(例如数据库)的数据的对象。您可能有一个映射器,用于将数据库中的数据映射到数据对象或从数据对象映射数据。然后,控制器将从您的模型类中获取数据,并将信息发送到视图,在该视图中处理实际的表示。在控制器中具有视图逻辑(html / javascript)是不可取的,并且直接与来自控制器的数据进行交互是相同的。
答案 3 :(得分:1)
首先,您需要查看类自动加载。这样您就不必包含您使用的每个类,只需使用它,自动加载器就会找到要包含的正确文件。
http://php.net/manual/en/language.oop5.autoload.php
每个班级都应该承担一项责任。您不会有一个连接到数据库的类,并更改一些用户数据。相反,您将拥有一个将传递给用户类的数据库类,而用户类将使用数据库类来访问数据库。每个职能部门也应承担一项责任。你永远不应该在函数名中加上“和”。
您不希望一个对象知道另一个对象的属性。这会导致在一个类中进行更改以强制您在另一个类中进行更改,并最终难以进行更改。属性应该由对象内部使用。
在开始编写课程之前,首先应考虑如何使用它(请参阅测试驱动开发)。在使用代码时,您希望代码看起来如何?
$user = new User($db_object);
$user->load($id);
$user->setName($new_name);
$user->save();
既然您已经知道如何使用它,那么以正确的方式编写代码会更容易。
当你有机会时研究敏捷原则。
答案 4 :(得分:0)
一个经验法则是类名通常应该是名词,因为OOP是关于拥有与真实概念对象相对应的软件对象。类成员函数通常是动词,即您可以对对象执行的操作。
在您的示例中,show是一个奇怪的类名。更典型的方法是使用名为show()或list()的成员函数创建一个名为ProductViewer的类。此外,您可以使用子类作为获取特定功能的方法,例如特定产品类型的自定义视图。