After my last article on interfaces a few people said it would have been clearer if I had given a better example. I decided to write this tutorial/article to further explain the use of interfaces (and to give a decent example).
The code in this article will solve the following real life problem that I recently had to solve: I needed a system that allowed me to send emails to different combinations of groups of users.
There were many different variations of "user groups" and so I needed a flexible system to allow me to easily send emails to different combinations of these groups and to also allow me to easily add, delete and change groups at a later date.
I decided I needed one core class (which I named GroupEmailer) and one interface (which I namded RecipientGroup). I will later create classes that implement that interface.
The class, GroupEmailer, is responsible for sending a specific email to a group of recipients. It must know which group of users we want to send emails to. I've left out the implementation of sending the actual email as I don't feel it is important to the example.
PHP Code:
class GroupEmailer
{
private $m_aGroups;
public function addGroup(RecipientGroup $pGroup)
{
$this->m_aGroups[] = $pGroup;
}
public function send()
{
foreach ($this->m_aGroups as $pGroup)
{
$aRecipients = $pGroup->getRecipients();
foreach ($aRecipients as $szRecipient)
{
echo $szRecipient . '<br />';
}
}
}
}
If you read the previous article on interfaces this should look very similar to the PagesController class and should therefore need little explanation. With that said, you should note that in the send() method I've simply looped through and printed out each recipient, in a real life situation we'd obviously be sending out emails instead of printing out the list of recipient addresses. In case you're wondering how you could do this, you could simply pass in the email details through the send() method, such as send('Subject', 'Message body').
You can probably imagine how this will work. We'll add "groups" to the class (using addGroup()) which represents the group of users that we want to email, then we'll call the send() method to send the emails to each member of the groups.
However, we've not actually got any code for returning the groups yet. You may have noticed that the addGroup() method is expecting an object that implements the RecipientGroup interface, this means that we need to create some classes that implement this interface. Before we do that, we need to create our interface:
PHP Code:
interface RecipientGroup
{
public function getRecipients();
}
We can determine that this interface needs only one method because each recipient group has only one responsibility: to return the list of recipient email addresses that belong to the group that it represents, for example, an Admin group would be responsible for returning a list of email addresses for all admins of the system.
Now that we have an interface to design our groups to we can start creating our group classes. We'll create two classes for this example, one for retrieving a list of admin email addresses and one for retrieving a list of member email addresses.
Here's the class for retrieving the list of admin email addresses:
PHP Code:
class RecipientGroup_Admins implements RecipientGroup
{
public function getRecipients()
{
// fetch list of admin emails from db
return array('karl@talkphp.com', 'wildhoney@talkphp.com',
'salathe@talkphp.com', 'bluesaga@talkphp.com');
}
}
Notice that we're not actually fetching any emails from anywhere, I've just hard-coded them so you can run the example and actually see how this would work before implementing it.
Here's the class for retrieving the list of member email addresses. This is almost exactly the same as the previous class
PHP Code:
class RecipientGroup_Members implements RecipientGroup
{
public function getRecipients()
{
// fetch list of member emails from db
return array('john@hotmail.com', 'peter@yahoo.com',
'paul@gmail.com', 'bob@aol.com');
}
}
Now that we have our two recipient groups we can give this a try:
PHP Code:
// Send an email to admins only
$pGroupEmailer = new GroupEmailer();
$pGroupEmailer->addGroup(new RecipientGroup_Admins());
$pGroupEmailer->send();
This would output the following:
Code:
karl@talkphp.com
wildhoney@talkphp.com
salathe@talkphp.com
bluesaga@talkphp.com
We can easily send to an additional group of users by adding that to the GroupEmailer
PHP Code:
// Let's send an email to admins and members
$pGroupEmailer = new GroupEmailer();
$pGroupEmailer->addGroup(new RecipientGroup_Admins());
$pGroupEmailer->addGroup(new RecipientGroup_Members());
$pGroupEmailer->send();
Running this code would send emails to both groups, resulting in:
Code:
karl@talkphp.com
wildhoney@talkphp.com
salathe@talkphp.com
bluesaga@talkphp.com
john@hotmail.com
peter@yahoo.com
paul@gmail.com
bob@aol.com
We've now got a flexible system for sending emails to groups of members. We could easily add more groups by creating more "group" classes. How you go about collecting the email addresses (for example, from a database or hard coded) is of no concern to EmailSender, this gives you the flexibility to add, delete and change groups as your project requirements change.