Php 这是正确实现的OOD吗?
我正在学习OO坚实的原则和设计模式,我想做一些实践。所以我从我正在进行的项目中得到一个问题,并尝试设计它。请检查它是否正确实施,或者它设计过度,或者我实施得很差。你的回答是最重要的 问题 我必须在一个系统中管理sms和电子邮件活动。我的意思是说将其存储在数据库中并检索它等等 因此,我认为会有一些特定的活动,如创建日期状态等。因此,我创建了名为campaignmodel的类,该类负责与活动相关的一些常见功能Php 这是正确实现的OOD吗?,php,oop,design-patterns,solid-principles,Php,Oop,Design Patterns,Solid Principles,我正在学习OO坚实的原则和设计模式,我想做一些实践。所以我从我正在进行的项目中得到一个问题,并尝试设计它。请检查它是否正确实施,或者它设计过度,或者我实施得很差。你的回答是最重要的 问题 我必须在一个系统中管理sms和电子邮件活动。我的意思是说将其存储在数据库中并检索它等等 因此,我认为会有一些特定的活动,如创建日期状态等。因此,我创建了名为campaignmodel的类,该类负责与活动相关的一些常见功能 Class CampaignModel { public function sav
Class CampaignModel
{
public function save($data)
{
// add campaign specific data
// save the campaign.
}
public function get()
{
// select the row from database and return it.
}
}
然后我做短信广告和电子邮件广告
class SMSCampaignModel extends CampaignModel
{
public function save($data)
{
// add sms specific data and
parent::save($data);
}
public function gets()
{
//fire the query to get the sms campaigns and returns it.
}
}
class EmailCampaignModel extends CampaignModel
{
public function save($data)
{
// add email specific data
parent::save($data);
}
public function gets()
{
//fire the query to get the email campaigns and returns it.
}
}
现在,每个活动都会有收件人,我们必须存储每个收件人的状态,如他打开邮件或发送邮件/短信或失败等。我认为我们会发送带有许多电子邮件或号码的活动,因此我决定创建不同的数据库表来存储这些详细信息,如短信活动日志,电子邮件、活动、日志等。我已经为它创建了界面
interface CampaignLogs
{
function insert_log();
function get_details();
}
class SmsCampaignLogs implements CampaignLogs
{
public function insert_log($data)
{
// get the number and status save it into the sms logs table.
}
public function get_details($campagin_id)
{
// get the logs from campagin table and return it.
}
}
class EmailCampaignLogs implements CampaignLogs
{
public function insert_log($data)
{
// get the number and status save it into the email logs table.
}
public function get_details($campagin_id)
{
// get the logs from campagin table and return it.
}
}
最后,我认为现在我应该使用策略模式来实现它(我不知道它是否正确)
现在是实现代码
$campaign = new SmCampaignModel();
$logger = new SmsCampaignLogs();
$c = new Campaign($campagin,$logger);
$c->save($data);
$c->get($campaign_id);
$c->get_campaing_details();
然后我想如果战略模式需要的话。
简单地说,我可以实现:
$campaign = new SmCampaignModel();
$logger = new SmsCampaignLogs();
$campaign->save($data);
$campaign->get($campaign_id);
$logger->get_campaing_details($campaign_id);
所以我现在完全糊涂了。我想听听你的意见,看看我在设计中是否正确地运用了坚实的原则(需要/正确地使用战略模式)。在这种情况下,你的竞选课只是一个幌子。没有使用任何策略 实际上,您使用的是Facades模式,而不是策略。你的竞选课没有自己的行为。它只是将其行为委托给子系统组件。这不是一件坏事,但它使您的代码更难维护。这在信息隐藏方面是很好的 在OOD方面没有对错之分。如果没有提出任何理由,则不必包括设计模式。你应该问自己:“我的主要问题是什么,这能解决吗?”。“是否有理由经常更改代码?” 因为我们有时都会被过度使用设计模式所诱惑,所以我想向您展示如何建立一个简单的OO关系,这样做会很好,甚至更易于阅读和维护
abstract class Campaign {
protected $ages;
protected $countries;
protected $dailyBudget;
protected $recipientsStatus = array(); // associative array or a composition of Recipients object
public function startCampaign()
{
// check there is not another run
$this->executeCampaign();
$this->collectRecipientsStatus();
$this->generateStatistics();
}
abstract protected function executeCampaign();
abstract protected function collectRecipientsStatus();
abstract protected function generateStatistics();
}
class EmailCampaign extends Campaign {
protected $addresses;
protected function executeCampaign()
{
$this->filterEmailsByCampaignData();
$this->sendEmails();
}
protected function filterEmailsByCampaignData()
{
// populate $this->addresses based on ages, countries etc.
}
protected function sendEmails()
{
// send email to addresses
}
protected function collectRecipientsStatus()
{
// collect status and fill parent $recipientsStatus
}
protected function generateStatistics()
{
// generate statistics
}
}
Campaign now是一个包含数据和行为的类。我们不必将其解耦为模型和日志之类的组件。这就行了。然而,如果您发现自己有一个更复杂的Recipients数组(太多的键值或维度数组代码),那么您可能会将其解耦到另一组类中。但这应该随着代码的发展而发生。我们根本无法提前预见一切
顺便说一句,我使用的唯一模式是轻量级模板方法和OOP的继承功能。那么我们可以把这个问题转移到那个网站上吗,或者我想在那里重写这个问题@decezeThis这个问题看起来像是一个非常精简的“裸骨”版本的实际代码。因此,它是“伪”代码,或者是假设代码,与codereview无关。se@Siddhesh迁移是可能的,但需要主持人干预,并且只有在给出了有用的答案/评论时才有必要。你不妨加快速度,自己把它发布到那里,然后删除这个。@deceze:不要试图把问题硬塞进CR。如果这个问题在这里离题了,那么就投票以适当的理由关闭它。你可以建议,一个问题可能是一个很好的CR适合,但投票结束一篇文章的第一条规则是,它实际上必须脱离主题。你滥用了习惯性的结束理由。@deceze:例如,这个问题可能太宽泛了。此时,您投票决定将其关闭,建议OP可能更适合CR(首先查看他们的主题帮助信息),并标记帖子,要求版主将其迁移。但是不要滥用自定义的投票结束消息。但是,先生@techwist您正在将所有活动功能合并到一个类中,因此SRP将被打破。此外,如果我改变电子邮件发送库或其他任何东西,它也将打破开放-关闭的原则?我想是的。sir代码看起来像是策略模式,这是我通过“头优先设计模式”的例子学到的。@Siddhesh,首先,外观不是模式的指标。实际上,有不同的模式,它们的OO结构/UML是相同的:状态、策略、桥接和适配器的实现完全相同。唯一的区别是意图和它们的性质。这不是他们如何解决问题,而是为什么。你是对的,SRP和原子性很重要。但我现在看到的是,Campaign类仅根据其数据启动活动。这是一个独特的功能。我分离了CRUD(db)操作,因为它不必是类的任务。@Siddhesh,正如我前面所写的:没有对或错。实际上,你写的代码做得很好。先发制人是个好的开始,我可以告诉你你做得很好。我的重点是向你们展示,有时候简单是成功的。您展示了一个很好的解决方案,但我唯一的疑问是该解决方案是否能帮助您满足当前项目所面临的需求。但是,如果您只尝试在设计模式上进行练习,请继续这样做。稍后,您将收集有效的工具来帮助自己。因此,当我们在使用oo时,应该使用这些模式,对吗?
abstract class Campaign {
protected $ages;
protected $countries;
protected $dailyBudget;
protected $recipientsStatus = array(); // associative array or a composition of Recipients object
public function startCampaign()
{
// check there is not another run
$this->executeCampaign();
$this->collectRecipientsStatus();
$this->generateStatistics();
}
abstract protected function executeCampaign();
abstract protected function collectRecipientsStatus();
abstract protected function generateStatistics();
}
class EmailCampaign extends Campaign {
protected $addresses;
protected function executeCampaign()
{
$this->filterEmailsByCampaignData();
$this->sendEmails();
}
protected function filterEmailsByCampaignData()
{
// populate $this->addresses based on ages, countries etc.
}
protected function sendEmails()
{
// send email to addresses
}
protected function collectRecipientsStatus()
{
// collect status and fill parent $recipientsStatus
}
protected function generateStatistics()
{
// generate statistics
}
}