Defining the factory method (creator interface) and its concrete implementation

The next step is to create a class and define the factory method that returns the abstract product type (MessageApp, in our case). This class is considered an abstract creator. The factory method would be in the form of either an interface or the abstract method. All concrete creators must implement this factory method. The following diagram describes the complete relationship between these components:

Here, MessagingService is the creator, while EmailServices, SMSServices, and WhatsAppServices are concrete creators. Each concrete creator produces the respective concrete product type.

The factory method and its concrete implementation classes should look as follows:

//Abstract creator
public abstract class MessagingService {
//This is Factory method.
public abstract MessageApp createMessageApp();
}

//Concrete creator
public class EmailServices extends MessagingService{
@Override
public MessageApp createMessageApp() {
return new EmailMessage();
}
}

//Concrete creator
public class SMSServices extends MessagingService {
@Override
public MessageApp createMessageApp() {
return new SMSMessage();
}
}

//Concrete creator
public class WhatsAppServices extends MessagingService {
@Override
public MessageApp createMessageApp() {
return new WhatsAppMessage();
}
}
In the preceding case, we have used an abstract class, but you can also use an interface for the factory method (abstract creator). If you are planning to provide any common methods, you can choose an abstract class, or else an interface would be an appropriate choice.

Finally, the factory class that provided the specific implementation looks as follows:

public class MessagingFactory {
public MessageApp getMessageApp(MessageType messageType) {
MessageApp messageApp = null;
// 1.Based on messageType value, create concrete implementation.
// 2.Call factory method on each of them to get abstract product type - MessageApp in our case
// 3.call common method on abstract product type to execute desire operation.

switch(messageType) {
case SMSType:
messageApp = new SMSServices().createMessageApp();
break;
case EmailType:
messageApp = new EmailServices().createMessageApp();
break;
case WhatsAppType:
messageApp = new WhatsAppServices().createMessageApp();
break;
default: System.out.println(" Unknown message type .. Please provide valid message type ");
}
return messageApp;
}
}

This class returns the concrete implementation based on a specific enum type. The following code snippet depicts how client code can use the factory method:

public class Client {
public static void main(String[] args) {
MessagingFactory messagingFactory = new MessagingFactory();
MessageApp smsApp = messagingFactory.getMessageApp(MessageType.SMSType);
MessageApp emailApp = messagingFactory.getMessageApp(MessageType.EmailType);
MessageApp whatsAppApp = messagingFactory.getMessageApp(MessageType.WhatsAppType);
smsApp.sendMessage(" Hello ");
emailApp.sendMessage(" this is test ");
whatsAppApp.sendMessage(" Good Morning");
}
}

This is described with the following diagram:

With the factory method pattern, you can make the product creation process abstracted from the client class. This way, the factory method pattern removes the dependency of the concrete product classes from the rest of the system. Additionally, the factory method delegates the actual object creation process to concrete creators. As long as the client code knows the type, the factory class will supply the dependency object of that type. This way, the factory method allows client code to depend on abstraction rather than concrete implementation. This is how IoC is achieved through the factory method pattern.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.117.214