我在OOP中并没有完全了解一些事情,我将使用对SO的虚构理解,看看我是否能得到帮助.
所以,在这个页面上我们有一个问题.你可以对这个问题发表评论.还有答案.你可以评论答案.
Question
- comment
- comment
- comment
Answer
-comment
Answer
-comment
-comment
-comment
Answer
-comment
-comment
所以,我想象对这种类型的系统有很高的理解(在PHP中,而不是.Net,因为我还不熟悉.Net)就像:
$question = new Question;
$question->load($this_question_id); // from the URL probably
echo $question->getTitle();
要加载答案,我想它就像这样(“A”):
$answers = new Answers;
$answers->loadFromQuestion($question->getID()); // or $answers->loadFromQuestion($this_question_id);
while($answer = $answers->getAnswer())
{
echo $answer->showFormatted();
}
或者,你会做(“B”):
$answers->setQuestion($question); // inject the whole obj, so we have access to all the data and public methods in $question
$answers->loadFromQuestion(); // the ID would be found via $this->question->getID() instead of from the argument passed in
while($answer = $answers->getAnswer())
{
echo $answer->showFormatted();
}
我想我的问题是,我不知道何时或是否应该传递整个对象,以及何时我应该传递一个值.传递整个对象给了我很大的灵活性,但它更多的内存并且可以改变,我猜(就像一个属性或方法重命名).如果“A”风格更好,为什么不使用一个功能呢? OOP在这里似乎毫无意义.
谢谢,
汉斯
解决方法:
虽然我喜欢杰森的答案,但严格来说,它不是OO.
$question = new Question($id);
$comments = $question->getComments();
$answers = $question->getAnswers();
echo $question->getTitle();
echo $question->getText();
foreach ($comments as $comment)
echo $comments->getText();
问题是:
>没有信息隐藏,这是OO的基本原则.
>如果答案的格式需要更改,则必须在与容纳数据的对象无关的位置更改答案的格式.
>解决方案不可扩展. (没有继承的行为.)
您必须保持与数据的行为(紧密耦合).否则你不是在写OO.
$question = new Question($id);
$questionView = new QuestionView( $question );
$questionView->displayComments();
$questionView->displayAnswers();
信息的显示方式现在是一个实现细节,可重复使用.
请注意这是如何开启以下可能性的:
$question = new Question( $id );
$questionView = new QuestionView( $question );
$questionView->setPrinterFriendly();
$questionView->displayComments();
$questionView->displayAnswers();
我们的想法是,现在您可以从代码库中的单个位置更改问题的格式.您可以支持多种格式的评论和答案,而无需调用代码(a); (b)需要改变(在很大程度上).
如果您在多个位置编写文本格式详细信息,因为您滥用访问器方法,那么任何未来维护者的生命都将是悲惨的.如果维护者是一个知道你住在哪里的精神病患者,你就会遇到麻烦.
对象,数据和视图
根据我的理解,这是问题所在:
Database -> Object -> Display Content
您希望将对象的行为保持在对象固有的逻辑的中心.换句话说,您不希望Object必须执行与其核心职责无关的事情.最常见的是,这将包括加载,保存和打印功能.您希望将这些与对象本身分开,因为如果您需要更改数据库或输出格式,您希望尽可能少地在系统中进行更改,并抑制涟漪效应.
为了简化这一点,让我们看看只加载评论;一切也适用于问题和答案.
评论类
Comment类可能提供以下行为:
>回复
>删除
>更新(需要许可)
>恢复(从删除)
>等
CommentDB类
我们可以创建一个知道如何操作数据库中的注释的CommentDB对象. CommentDB对象具有以下行为:
>创建
>加载
>保存
>更新
>删除
>恢复
请注意,这些行为可能在所有对象中都很常见,因此可能会进行重构.这也可以让您轻松更改数据库,因为连接信息将被隔离到单个类(所有数据库对象的祖父).
用法示例:
$commentDb = new CommentDB();
$comment = $commentDb->create();
后来:
$comment->update( "new text" );
请注意,有许多可能的方法可以实现这一点,但您可以始终这样做而不会违反封装和信息隐藏.
CommentView类
最后,CommentView类将与Comment类紧密耦合.它可以通过访问器获取Comment类的属性.该信息仍然隐藏在系统的其余部分. Comment和它的CommentView是紧密耦合的.这个想法是格式化保存在一个地方,而不是分散在需要使用数据的类中.
任何需要显示注释但是格式略有不同的类都可以从CommentView继承.
标签:php,oop
来源: https://codeday.me/bug/20190726/1544555.html