这个 OOD 是否正确实施?
Is this OOD implemented correctly?
我正在学习 OO SOLID 原则和设计模式,我想对其进行一些练习。所以我从我正在进行的项目中得到一个问题并尝试设计它。请检查它是否正确实施或过度设计或我实施不佳。您的回复最重要。
问题
我必须在一个系统中管理短信和电子邮件活动。我的意思是说将它存储在数据库中并检索它等。
所以我认为会有一些特定于活动的内容,例如创建日期状态等。因此我制作了 class 命名的活动模型,它负责与活动相关的一些常见功能
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.
}
}
现在每个活动都会有收件人,我们必须存储每个收件人的状态,例如他打开邮件或 mail/sms 已发送或失败等。我认为我们将发送带有许多电子邮件或号码的活动,所以我决定创建不同的数据库 table 用于存储 sms_campaign_log、email_campaign_log 等详细信息。我已经为它创建了接口
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.
}
}
最后我觉得现在应该用策略模式来实现(不知道对不对)
class Campaign
{
private $log;
private $campaign_type;
public function __construct($campaign, $logger)
{
$this->campaign_type = $campaign;
$this->log = $logger;
}
public function save($data)
{
$this->campagin_type->save();
}
public function gets()
{
$this->campaign_type->gets();
}
public function log($data)
{
$this->log->insert_log($data);
}
public function get_campaign_details($campaign_id)
{
$this->log->get_details($campaign_id);
}
}
现在实现代码。
$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);
所以我现在完全糊涂了。我想知道我是否在我的设计中正确应用了 SOLID 原则(策略模式 needed/used 是否正确)。
在这种情况下,您的广告系列 class 只是一个外观。没有正在使用的策略。
您实际上使用的是 Facades 模式,而不是 Strategy。您的广告系列 class 没有自己的行为。它只是将其行为委托给子系统组件。这不是一件坏事,但它使您的代码更难维护。信息隐藏方面还是可以的
OOD方面没有对错之分。如果没有给出理由,则不必包括设计模式。你应该问问自己:"What is my main problem, and does this solve it?"。 "Will there be a reason to the code to be changed often?".
因为我们有时都想过度使用设计模式,所以我想向您展示如何建立一个简单的 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
}
}
活动现在是一个包含数据和行为的 class。我们不必将其解耦为 Model 和 Logs 等组件。这会很好用。但是,如果您发现自己的 Recipients 数组有点复杂(键值太多或维数组代码有味道),那么您可能会将其解耦到另一组 classes 中。但这应该随着代码的演变而发生。我们根本无法提前预见一切。
顺便说一下,我使用的唯一模式是轻量级模板方法和 OOP 的继承特性。
我正在学习 OO SOLID 原则和设计模式,我想对其进行一些练习。所以我从我正在进行的项目中得到一个问题并尝试设计它。请检查它是否正确实施或过度设计或我实施不佳。您的回复最重要。
问题 我必须在一个系统中管理短信和电子邮件活动。我的意思是说将它存储在数据库中并检索它等。
所以我认为会有一些特定于活动的内容,例如创建日期状态等。因此我制作了 class 命名的活动模型,它负责与活动相关的一些常见功能
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.
}
}
现在每个活动都会有收件人,我们必须存储每个收件人的状态,例如他打开邮件或 mail/sms 已发送或失败等。我认为我们将发送带有许多电子邮件或号码的活动,所以我决定创建不同的数据库 table 用于存储 sms_campaign_log、email_campaign_log 等详细信息。我已经为它创建了接口
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.
}
}
最后我觉得现在应该用策略模式来实现(不知道对不对)
class Campaign
{
private $log;
private $campaign_type;
public function __construct($campaign, $logger)
{
$this->campaign_type = $campaign;
$this->log = $logger;
}
public function save($data)
{
$this->campagin_type->save();
}
public function gets()
{
$this->campaign_type->gets();
}
public function log($data)
{
$this->log->insert_log($data);
}
public function get_campaign_details($campaign_id)
{
$this->log->get_details($campaign_id);
}
}
现在实现代码。
$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);
所以我现在完全糊涂了。我想知道我是否在我的设计中正确应用了 SOLID 原则(策略模式 needed/used 是否正确)。
在这种情况下,您的广告系列 class 只是一个外观。没有正在使用的策略。
您实际上使用的是 Facades 模式,而不是 Strategy。您的广告系列 class 没有自己的行为。它只是将其行为委托给子系统组件。这不是一件坏事,但它使您的代码更难维护。信息隐藏方面还是可以的
OOD方面没有对错之分。如果没有给出理由,则不必包括设计模式。你应该问问自己:"What is my main problem, and does this solve it?"。 "Will there be a reason to the code to be changed often?".
因为我们有时都想过度使用设计模式,所以我想向您展示如何建立一个简单的 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
}
}
活动现在是一个包含数据和行为的 class。我们不必将其解耦为 Model 和 Logs 等组件。这会很好用。但是,如果您发现自己的 Recipients 数组有点复杂(键值太多或维数组代码有味道),那么您可能会将其解耦到另一组 classes 中。但这应该随着代码的演变而发生。我们根本无法提前预见一切。
顺便说一下,我使用的唯一模式是轻量级模板方法和 OOP 的继承特性。