Php 面向对象设计问题
我是在PHP中使用OOP的新手。它对我的代码的组织和维护有很大帮助,但我希望在设计类和尽可能高效地使用OOP方面做得更好。我读过四人帮设计模式的书,但仍然需要一些帮助。在构建了一些小应用程序之后,我一直在想一件事 假设我正在构建一个应用程序来跟踪学校的注册信息 我目前的做法是创建一个名为Php 面向对象设计问题,php,oop,Php,Oop,我是在PHP中使用OOP的新手。它对我的代码的组织和维护有很大帮助,但我希望在设计类和尽可能高效地使用OOP方面做得更好。我读过四人帮设计模式的书,但仍然需要一些帮助。在构建了一些小应用程序之后,我一直在想一件事 假设我正在构建一个应用程序来跟踪学校的注册信息 我目前的做法是创建一个名为student的类,并在该类中为每个学生的记录上的CRUD创建方法。似乎合乎逻辑的是,我会为这个类提供一个构造函数方法,该方法将student\u id作为参数,这样我就可以从对象中引用它来执行所有这些不同的CR
student
的类,并在该类中为每个学生的记录上的CRUD创建方法。似乎合乎逻辑的是,我会为这个类提供一个构造函数方法,该方法将student\u id
作为参数,这样我就可以从对象中引用它来执行所有这些不同的CRUD操作
但是,当我继续构建应用程序时,我遇到了需要运行返回多个学生的查询的情况。例如,
get_all_students\u from_grade($grade)
,get_dropdown\u of_all_students()
,等等。这些方法并不只适用于一个学生,所以在我的student
类中将它们作为方法似乎很奇怪,因为我在实例化对象时考虑了一个student\u id
。显然,我可以这样做,但似乎我“做错了”。解决这个问题的最佳方法是什么?您应该在Student上创建它们。将Student
类(这是一个域类)与它的操作(业务逻辑或数据访问,取决于具体情况)分开,如:
-域对象仅包含数据student
或student\u service
(数据访问对象)-执行操作student\u dao
关于此事的更多信息。从OOP的角度来看,它提供了比破坏封装更多的缺点。因此,尽管这似乎是一种公认的做法,但并不完全是面向对象的。将其分为两类:
$students = student_repository.get_all_students_from_grade($grade)
你可以使用工厂方法,让工厂决定新生的ID应该是什么 当然,这个工厂必须读取一个数据库来查看索引的起始位置(基于数据库中的学生数量),并且您必须决定如何处理被删除的学生(如果可能的话) 至于你所描述的方法,我不明白你为什么要把它们包括在学生课堂上。您可以,但它应该是一个静态方法,而不是成员方法。我并不假装知道“最佳”方法,但它可能有助于以不同的方式处理问题。您可以让类表示应用程序和数据库之间的数据接口,而不是让一个类表示单个学生 这个类将知道如何从数据库中检索一组(可能是一个)学生行,将它们缓存在本地数组中,允许应用程序浏览缓存的记录,允许对缓存的记录进行修改,完成后,将缓存的修改写回数据库(通过生成SQL来说明更改)
这样,您可以避免为每次更改触发单个SQL语句(您仍然使用一组行),同时提供对单个对象的访问(通过维护缓存中当前位置的索引,并允许应用程序在调用类的方法时推进此“指针”)正如尼尔在评论中所说(不确定为什么我们没有给出答案),你可能还应该上
课程和学校课程。您可以在学校
中使用特定于学校的方法(让给定年级的所有学生都参加,缺课天数给定等),在课程
中使用特定于课程的方法(某一课程的所有学生都参加,等)
您认为,在标准CRUD中,您不希望赋予代表个人的类(即学生
类)加载自身倍数的责任,这是正确的另一方面,如果您想要更多的数据加载方式(这是RubyonRails所采用的),那么您实际上会在Student
类本身上创建所有Student
加载程序方法静态方法。它只取决于您想要如何设置样式,这在一定程度上取决于您的数据模型将变得多么复杂。始终有一个起点。在你的情况下,这将是你从学生那里得到的东西(即学校、班级等)
我遇到了同样的问题,我猜你在使用MySQL?这是一个常见的OOP设计挑战,因为SQL有一种将所有内容扁平化的趋势
我通过以下步骤解决了这个问题
1.)创建一个具有三种实例化形式的类
一个新的地方
$myStudent = new $Student();
另一种情况是,您知道id,但需要id数据
$myStudent = new $Student($student_id);
另一种情况是,它的数据已经存在于关联数组中
$data = array('id'=13,'name' => 'studentname', 'major' => 'compsci');
$myStudent = new $Student($data['id'], $data);
这允许您创建一个factory类,该类可以从mysql运行查询,获取数据的关联数组,然后从该数组数据创建student实例,而无需访问student每个实例的数据库
下面是此类的构造函数:
public function __construct($id=FALSE, $data=FALSE)
{
if(!$id) $this->is_new = true;
else if($id && !$data) $this->get_data_from_db($id);
else if($id && $data) $this->set_data($data);
}
如果你有“学生”,你可能还想要“课程”和“学校”,这似乎是“获得学生”方法的好地方。这听起来是最简单的方法。您能否描述/提供描述“域”类/对象概念的链接?马修:马丁·福勒(Martin Fowler)的书(应用UML和模式)中对它进行了很好的描述,但是我没有发现任何东西
public function __construct($id=FALSE, $data=FALSE)
{
if(!$id) $this->is_new = true;
else if($id && !$data) $this->get_data_from_db($id);
else if($id && $data) $this->set_data($data);
}