我只是想知道我是否走在正确的道路上。使大多数函数抽象似乎没有必要,因为数据几乎相同。这是一种无效的方法吗?
<?php
abstract class Model_Tasks {
/**
* Database object
*
* @access protected
*/
protected $db;
/**
* User ID
*
* @access protected
*/
protected $uid;
/**
* Data array
*
* @access protected
*/
protected $data;
/**
* SQL Query
*
* @access protected
*/
protected $query;
/**
* __construct
*
* @access protected
*/
protected function __construct($query) {
$this->db = Model_DB::getInstance();
$this->uid = $_SESSION['uid'];
$this->query = $query;
$this->getTasks();
}
/**
* getTasks
*
* @param string
* @access abstract protected
*/
protected function getTasks() {
$result = $this->db->prepare($this->query);
$result->execute(array(
':uid' => $this->uid
));
$this->data =& $result->fetchAll();
$this->taskCount = $result->rowCount();
}
/**
* constructTask
*
* Build the HTML of a task
*
* @param int
* @param int
* @param string
* @param string
* @access protected
*/
protected function constructTask(
$id, $cost, $title, $checked = 0
) {
$cost = money_format('$%i', $cost);
$title = stripslashes($title);
return '
<label class="task">
<input type="checkbox" name="done[]" rel="'.$id.'" '.($checked?'checked="checked"':'').' />
<code>'.$cost.'</code> — '.$title.'
</label>'."\n";
}
/**
* generateOutput
*
* Call by key [pending, completed] and return the constructed tasks
*
* @param bool
* @access final public
*/
final public function generateOutput($checked) {
try {
if(!is_bool($checked)) throw new Exception('generateOutput must contain a boolean variable');
if(!isset($this->data)) throw new Exception('Array has not been set.');
else $data = $this->data;
} catch(Exception $e) {
die('<pre>'.$e->getMessage().'<hr />'.$e->getTraceAsString());
}
if(is_array($data)): foreach($data AS &$r)
$str .= $this->constructTask($r['id'], $r['cost'], $r['title'], $checked);
else:
$str = '<label class="tasks"></label>';
endif;
return $str;
}
}
// ------------------------------------------------------------------------
/**
* pendingTasks
*
* @access public
*/
class pendingTasks extends Model_Tasks {
public $taskCount;
public function __construct() {
$query = '
SELECT id, title, cost
FROM tasks
WHERE (
status IS FALSE
AND uid = :uid
) ORDER BY cost DESC
';
parent::__construct($query);
}
}
/**
* completedTasks
*
* @access public
*/
class completedTasks extends Model_Tasks {
public function __construct() {
$query = '
SELECT id, title, cost
FROM tasks
WHERE (
status IS TRUE
AND uid = :uid
) ORDER BY id DESC
LIMIT 7
';
parent::__construct($query);
}
}
所有这一切都是打印出具有特定查询的任务,并返回一个关联数组。
答案 0 :(得分:2)
“这是一种无效的方法吗?”
没有。您的代码正确使用抽象。您可以集中共同的逻辑,但是通过将父类声明为抽象,您正在强制通过子类(扩展您的抽象,父类)来完成类的实例化,这很有效。
建议:
$this->uid = $_SESSION['uid'];
以这种方式声明成员变量会破坏封装。我建议你通过调用代码分配这样的成员变量,而不是在构造函数中。
答案 1 :(得分:0)
从抽象类继承时,父类声明中标记为abstract的所有方法都必须由子类定义;此外,必须使用相同(或限制较少)的可见性来定义这些方法。例如,如果将抽象方法定义为protected,则必须将函数实现定义为protected或public,而不是private。此外,方法的签名必须匹配,即类型提示和所需参数的数量必须相同。 这也适用于PHP 5.4中的构造函数。在5.4构造函数签名可能不同之前。 - php.net
在您的实现中,构造函数的签名是不同的..
答案 2 :(得分:0)
这是一个使用抽象类的时间的真实例子:小部件。
我有一个小部件模型,它具有创建,编辑,保存或呈现小部件所需的大部分功能。但是,有两个基本指标我需要这个类是抽象的:
edit()
方法和render()
方法,因为照片小部件具有不同的属性,并且应该与推文小部件显示不同。