这个OOD是否正确实施?

时间:2015-07-15 07:16:23

标签: php oop design-patterns solid-principles

我正在学习OO SOLID原则和设计模式,我想对它做一些练习。所以我从正在进行的项目中得到了一个问题并尝试设计它。请检查它是否正确实施或是否过度设计或我实施得不好。你的回答是最重要的。

问题 我必须在一个系统中管理短信和电子邮件活动。我的意思是说将它存储在数据库中并检索它等。

所以我认为广告系列会有特定的内容,例如创建的日期状态等。因此,我创建了名为campaignmodel的类,它负责与广告系列相关的一些常见功能

Class CampaignModel
{
    public function save($data)
    {
        // add campaign specific data
        // save the campaign.

    }

    public function get()
    {
        // select the row from database and return it.

    }
}

然后我制作了smscampaign和电子邮件广告系列

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.
    }

}

现在每个广告系列都有收件人,我们必须存储每个收件人的状态,比如他打开邮件或邮件/短信发送或失败等等。我想我们会发送包含许多电子邮件或号码的广告系列,所以我决定创建不同的数据库表来存储诸如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原则(以及是否需要/使用策略模式)提出意见。

1 个答案:

答案 0 :(得分:3)

在这种情况下,您的Campaign类只是一个Facade。没有策略在使用。

您实际上使用的是Facades模式,而不是策略。您的Campaign类没有自己的行为。它只是将其行为委托给子系统组件。这不是一件坏事,但它会使您的代码难以维护。信息隐藏方面很好。

OOD方面没有对错。如果没有提出任何理由,则不必包括设计模式。你应该问问自己:"我的主要问题是什么,这解决了吗?"。 "是否有理由经常更改代码?"。

因为我们有时候都试图过度使用设计模式,所以我想向您展示如何使一个简单的OO关系做得很好,甚至更容易阅读和维护。

private static PointF ClosestPointToSegment(PointF P, PointF A, PointF B)
{
    PointF a_to_p = new PointF(), a_to_b = new PointF();
    a_to_p.X = P.X - A.X;
    a_to_p.Y = P.Y - A.Y; //     # Storing vector A->P  
    a_to_b.X = B.X - A.X;
    a_to_b.Y = B.Y - A.Y; //     # Storing vector A->B

    float atb2 = a_to_b.X * a_to_b.X + a_to_b.Y * a_to_b.Y;
    float atp_dot_atb = a_to_p.X * a_to_b.X + a_to_p.Y * a_to_b.Y; // The dot product of a_to_p and a_to_b
    float t = atp_dot_atb / atb2;  //  # The normalized "distance" from a to the closest point
    return new PointF(A.X + a_to_b.X * t, A.Y + a_to_b.Y * t);
}

Campaign现在是一个包含数据和行为的类。我们不必将其与模型和日志等组件分离。这将工作得很好。但是,如果你发现自己有一些更复杂的Recipients数组(太多的键值或维数组代码气味),那么你可以将它解耦到另一组类中。但这应该随着代码的演变而发生。我们根本无法提前预见到所有事情。

顺便说一句,我使用的唯一模式是轻量级的模板方法和OOP的继承功能。