dqg2269 2015-07-15 07:16
浏览 36
已采纳

这个OOD是否正确实施?

I am learning OO SOLID principles and design patterns and I want to do some practice on it. So I get the one problem from my ongoing project and try to design it. Please check whether it is implemented correctly or it's over-engineered or I implement it poorly. Your response is most important.

Problem I have to manage sms and email campaigns in one system. I meant to say storing it in database and retrieving it etc.

So I think there will be something specific to the Campaign like created date status etc. Thus I have made the class named campaignmodel which is responsible for some common functions related to campaign

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

    }

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

    }
}

then I make smscampaign and email campaign

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

}

Now every campaign will have recipients and we have to store each recipient's status like he opens mail or mail/sms sent or failed etc. I think we will send the campaigns with many emails or numbers so I decided to create different database table for storing such details such as sms_campaign_log, email_campaign_log etc. I have created the interface for 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.
    }
}

and lastly I think now I should use strategy pattern to implement it(I don't know whether it is correct or not).

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);
    }
}

now Implementation code.

$campaign = new SmCampaignModel();
$logger = new SmsCampaignLogs();
$c = new Campaign($campagin,$logger);
$c->save($data);
$c->get($campaign_id);
$c->get_campaing_details();

Then I think if strategy pattern needed. Simply, I can implement:

    $campaign = new SmCampaignModel();
    $logger = new SmsCampaignLogs();
    $campaign->save($data);
    $campaign->get($campaign_id);
    $logger->get_campaing_details($campaign_id);

So I am now totally confused. I want your opinion on whether I applied SOLID principles correctly in my design (and strategy pattern is needed/used properly) or not.

  • 写回答

1条回答 默认 最新

  • dongyao4003 2015-07-15 10:34
    关注

    In this case your Campaign class is only a Facade. No Strategy is in use.

    You are actually using the Facades pattern and not the Strategy. Your Campaign class doesn't have a behavior of it own. It merely delegates its behavior to subsystem components. It is not a bad thing, but it makes your code somehow harder to maintain. It is fine in terms of information hiding.

    There is not right or wrong in the aspect of OOD. Design patterns are not must to be included if no reason is presented. You should ask yourself: "What is my main problem, and does this solve it?". "Will there be a reason to the code to be changed often?".

    Because we are all sometimes tempted to overuse design patterns, I would like to show you how making a simple OO relationship will do just fine, and will even be easier to read and maintain.

    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 is a class with data and behavior. We don't have to decouple it into components like Model and Logs. This will work just fine. However, if you ever find yourself with a bit more complicated Recipients array (too many key values or dimensional array code smells), then you might decouple it into another set of classes. But this should happen with evolution of the code. We simply cannot foresee everything in advance.

    By the way, the only pattern I used is the lightweight Template Method, and inheritance feature of OOP.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序