Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/244.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使我的邮件列表管理器类更紧密地耦合?_Php_Object_Loose Coupling - Fatal编程技术网

Php 如何使我的邮件列表管理器类更紧密地耦合?

Php 如何使我的邮件列表管理器类更紧密地耦合?,php,object,loose-coupling,Php,Object,Loose Coupling,我正在做一个简单的项目,涉及潜在客户和报价。该项目将与第三方邮件列表提供商集成,后者将使用Prospect对象管理列表上的电子邮件地址,并提供对象来管理活动 我担心的一个问题是,任何邮件列表提供商(例如MailChimp)可能会决定停止提供服务,或者在将来更改条款。我不想让我的软件依赖于提供者,而是想让它依赖于一个通用接口,这个接口可以使用一个使用不同邮件列表提供者的不同类重新实现。这样,如果真的发生了这样的事情,我只需编写一个新类并在旧类的位置进行实例化 这似乎很容易实现。我的抽象类(包含在下

我正在做一个简单的项目,涉及潜在客户和报价。该项目将与第三方邮件列表提供商集成,后者将使用Prospect对象管理列表上的电子邮件地址,并提供对象来管理活动

我担心的一个问题是,任何邮件列表提供商(例如MailChimp)可能会决定停止提供服务,或者在将来更改条款。我不想让我的软件依赖于提供者,而是想让它依赖于一个通用接口,这个接口可以使用一个使用不同邮件列表提供者的不同类重新实现。这样,如果真的发生了这样的事情,我只需编写一个新类并在旧类的位置进行实例化

这似乎很容易实现。我的抽象类(包含在下面)定义了抽象方法,这些方法接受Prospect或Offer对象,并对它们执行与通用邮件列表相关的函数,在需要时返回真/假或整数值。这个接口应该很好地满足我的应用程序的需要

<?php
/**
 * MailingList file.
 *
 * Contains the class definition for the abstract class Monty_MailingList.
 * @author Lewis Bassett <lewis.bassett@bassettprovidentia.com>
 * @version 0.1
 * @package Monty
 */

/**
 * Represents the interface for all MailingList classes.
 *
 * Adhereing to this interface means that if a MailingList provider
 * (e.g., MailChimp) stops a service, a new class can extend this interface and
 * be replace the obsolete class with no need to modify any of the client code.
 *
 * @author Lewis Bassett <lewis.bassett@bassettprovidentia.com>
 * @version 0.1
 * @package Monty
 * @copyright Copyright (c) 2011, Bassett Providentia
 */
abstract class Monty_MailingList
{
    /**
     * Adds the passed prospect to the mailing list, or returns false if the
     * prospect already exists. Throws an error if the prospect could not be
     * added for any reason (other than it already existing).
     *
     * @param Monty_Prospect $prospect The prospect object to be added to the
     * mailing list.
     * @return bool Whether or not the prospect was added.
     */
    abstract public function addProspect(Monty_Prospect $prospect);

    /**
     * Updates the properties stored on the mailing list of the passed prospect,
     * or returns false if no data was updated. If the prospect is not found, a
     * they are added to the list. Throws an error if the prospect could not be
     * added or updated for any readon.
     *
     * @param Monty_Prospect $prospect The prospect object whose mailing list
     * data is to be updated.
     * @return bool Whether or not the prospect was updated.
     */
    abstract public function updateProspect(Monty_Prospect $prospect);

    /**
     * Returns true if the passed prospect object could be found on the mailing
     * list.
     *
     * @param Monty_Prospect $prospect The prospect object to be searched for.
     * @return bool Whether or not the prospect was found.
     */
    abstract public function findProspect(Monty_Prospect $prospect);

    /**
     * Deletes the passed prospect from the mailing list, or returns false if
     * the passed object is not found on the mailing list.
     *
     * @param Monty_Prospect $prospect The prospect to be deleted.
     * @return bool Whether or not the prospect was deleted.
     */
    abstract public function deleteProspect(Monty_Prospect $prospect);

    /**
     * Creates a campaign for the passed offer object, or returns false if the
     * campaign already exists. Throws an error if the campaign could not be
     * created for any reason (other than it already existing).
     *
     * @param Monty_Offer $offer The offer to be created.
     * @return bool Whether or not the offer was created.
     */
    abstract public function createOffer(Monty_Offer $offer);

    /**
     * Sends the campaign for the passed offer object, or returns false if the
     * campaign could not be sent for a reasonable reason (run out of credit or
     * something). If the campaign does not yet exist, it is created. Throws an
     * error if the campaign could not be created, or an was not sent for an
     * unknown reason.
     *
     * @param Monty_Offer $offer The offer to be sent.
     * @return bool Whether or not the offer was sent.
     */
    abstract public function sendOffer(Monty_Offer $offer);

    /**
     * Returns true if a campaign for the passed offer object could be found on
     * the mailing list.
     *
     * @param Monty_Offer $offer The offer to be searched for,
     * @return bool Whether or not the offer was found.
     */
    abstract public function findOffer(Monty_Offer $offer);

    /**
     * Returns the ammount of opens registered for the passed offer. Throws an
     * error if a campaign is not found for the passed offer.
     *
     * @param Monty_Offer $offer The offer in question.
     * @return int The ammount of registered opens for that offer.
     */
    abstract public function getOfferOpens(Monty_Offer $offer);

    /**
     * Returns the ammount of clicks registered for the passed offer. Throws an
     * error if a campaign is not found for the passed offer.
     *
     * @param Monty_Offer $offer The offer in question.
     * @return int The ammount of registered clicks for that offer.
     */
    abstract public function getOfferClicks(Monty_Offer $offer);

    /**
     * Returns the ammount of bounces registered for the passed offer. Throws an
     * error if a campaign is not found for the passed offer.
     *
     * @param Monty_Offer $offer The offer in question.
     * @return int The ammount of registered bounces for that offer.
     */
    abstract public function getOfferBounces(Monty_Offer $offer);

    /**
     * Returns the ammount of unsubscribes registered for the passed offer.
     * Throws an error if a campaign is not found for the passed offer.
     *
     * @param Monty_Offer $offer The offer in question.
     * @return int The ammount of registered unsubscribes for that offer.
     */
    abstract public function getOfferUnsubscribes(Monty_Offer $offer);
}

如果您想要更通用的方法,请创建一个类,在该类中添加人员而不是潜在客户,并添加电子邮件而不是提供,即(任何)邮件列表的通用接口。然后让你的Monty_邮件列表继承通用列表。

我在某些方面同意Emil的观点

你在这里混淆视听。您的类称为邮件列表,它应该和潜在客户和提供的内容无关,但包含您希望发送给他们的人员和内容

Prospect和Offers是业务逻辑模型,可以通过电子邮件向用户发送一个表示,因为在呈现到web页面时,用户可以使用另一个表示。从邮件中收集统计数据也是另外一回事


有一件事我不同意,那就是关于继承的问题,因为我通常不会这么做。在这里,我不会继承任何东西,而是创建单独的类来处理它们的部分并使用组合。

经过进一步思考,我想出了我认为最好的解决方案,这要归功于设计模式的一些灵感:可重用面向对象软件的元素(埃里克·伽马、理查德·赫尔姆、拉尔夫·约翰逊和约翰·维利塞德斯)

我现在有两个抽象类:

MailingListRecipient-为表示邮件列表收件人的对象定义接口。所有客户端代码都将为此接口编写,不关心此抽象代码的哪个子类实现它。它将具有设置名字、姓氏和电子邮件地址以及添加、更新、删除和删除的方法在邮件列表中找到收件人

MailingListMessage-为将在邮件列表上表示消息的对象定义接口,并将定义一些setter方法和一些操作。同样,将为此接口编写客户端代码,而不关心子类如何实现它

然后我将有一个抽象的工厂类:

MailingListFactory-这将在我的客户端代码中创建MailingListRecipient和MailingListMessage对象

因此,对于真正的实现,我将创建:

MailChimpRecipient-在MailChimp列表上表示收件人。此处的代码将遵循MailingListRecipient定义的接口,并且对象在其构造函数中需要API键和ListId

MailChimpMessage-表示MailChimp列表上的消息。此处的代码将遵循MailingListMessage定义的接口,并且此对象在其构造函数中也需要API键和ListId

我的客户端代码不会与上面两个对象中的任何一个进行交互。相反,在我的一个设置文件中,我将创建以下对象:

MailChimp工厂-用于创建MailChimp收件人和邮件。对象需要API键和ListId,然后将它们传递给上述两个类的构造函数,以创建MailChimp特定的对象

因此,在我的设置代码中,我将创建一个factory对象:

$mailingListFactory = new MailChimpFactory($apiKey, $listId);
然后,在我的客户端代码中,将创建新的收件人和邮件,从而:

$recipient = $mailingListFactory->createMailingListRecipient();
从那时起,它将能够设置和执行操作:

$recipient->setForename('Lewis');
$recipient->setEmailAddress('lewis@example.com');
$recipient->add();
如果MailChimp突然停止服务,或者我决定使用另一个邮件列表提供程序,我将创建MailingListRecipient和MailingListMessage的新子类,它们使用新的提供程序-它们的接口将是相同的,客户端代码将不知道或不关心它的不同

然后,我将创建MailingListFactory的新子类,该子类将创建新类的新收件人和邮件对象。我需要做的只是更改设置文件中的实例化:

$mailingListFactory = new newMailingListProviderFactory($username, $password);
因为我的其余代码是为抽象工厂中定义的接口编写的,所以不需要更改任何其他内容

使用抽象工厂可以确保我永远不会陷入代码使用mailChimpRecipient对象和newMailingListProviderMessage对象的情况

这符合我的两个目标:

可互换性-我可以交换我的邮件列表类,代码仍然可以像以前一样工作

可重用性——我可以使用这些类并在其他项目中使用它们


这似乎是最优雅的方式。如果其他人有更好的方式,我很乐意听到。谢谢大家的回复。

构图是另一种方式,是的,但我认为继承是首选方式,因为他实际上想要一个特殊的邮件列表,您可以在其中添加潜在客户和优惠。构图更重要这是一种必要的方式,事实上,它确实使代码更紧密地耦合,因为潜在客户/报价列表需要将通用邮件列表作为其参数(如果他稍后将通用列表发送到其他地方会发生什么情况?潜在客户是否神奇地与其他类型的人联系在一起?)。如果