Factory design issues

I am trying to create a bot for Messenger Messenger, trying to learn OOP. I really lost how to approach the problem. I have a message object, with all receivers and setters, which I find rather complicated. My problem is that I want to create two (or more) types of plants

1) a simple message where you just load the factory with chat_id, which you want to send a message and text that could be something like this:

<?php namespace Telegram\Domain\Factory; use Telegram\Domain\Entity\Message; class MessageRaw extends MessageAbstract { public function createMessage($chat_id, $text) { $message = new Message(); $message->setChatId($chat_id); $message->setText($text); return $message; } } 

where is MessageAbstract

 <?php namespace Telegram\Domain\Factory; abstract class MessageAbstract { abstract public function createMessage($chat_id, $text); } 

2) A message with a keyboard (Telegram gives you the ability to add a custom keyboard when sending a message). I have a problem, the keyboard is set as an array, so this will be another argument for createMessage.

So my problem is, should I always specify the $ keyboard argument, be it a simple message or a message with a keyboard? Or are these two types of messages different enough that they can be created from different classes (I think not)? Or maybe I shouldn't do this in a factory, but with setters and getters?

TL; DR: how to create an object with a different number of arguments in a fantastic way, something like this

 $MessageRaw = new MessageRaw($chat_id, $text); $MessageNumericKeyboard = new MessageNumericKeyboard($chat_id, $text); //numeric keyboard is standard so can be set in the createMessage Function $MessageCustomKeyboard = new MessageCustomKeyboard($chat_id, $text, ['A', 'B']); //should it be done like this? 
+6
source share
2 answers

I agree with @ CD001 regarding subtyping / extension, so I will not repeat his answer, but you can still use the factory template, specifying the required type, using dependency injection and returning the corresponding object.

You can include the selected parameter for this dependency in the factory method, or you can use the method overload to enter it and check only those specific types (if there are additional classes that can be returned outside of the two specified).

Adhering to the factory template, you can really expand it along the road without unnecessary additional work, now cutting corners will only lead to pain.


EDIT:

Injection (nb: I included a type parameter to cover one possible extension technique with a string, but it can also be a nested type object, right up to you. The ability to enter your message attributes at the same time for the message constructor, so you return a fully created object , not an empty DTO)

 class MessageFactory { public static function get($type,$attributes=NULL,$keyboard=NULL) { if ($keyboard && !($keyboard instanceof MessageKeyboardInterface)) { // ... trigger some exception here } elseif (!$keyboard) { $keyboard = new BasicKeyboard(); } switch($type): case('standard'): return new StandardMessage($attributes,$keyboard); break; case('short'): return new ShortMessage($attributes,$keyboard); break; case('long'): return new LongMessage($attributes,$keyboard); break; endswitch; } } 

This way, all of your Message objects can use the same interface, use custom or basic keyboards, and easily expand. Of course, you could expand the $ attributes and use your individual setters after creating the instance or iterate over them in the constructor if you have a lot of them. I personally don't like the ton of parameters in the contsructor and would prefer a loop over an array of optional parameters.

+4
source

This looks better than a regular or garden setting, rather than using a Factory template, for example:

 class Message { // eg protected $chatId; protected $text; // constructor public function __construct($chatId, $text) { $this->setChatId($chatId); $this->setText($text); } // ... stuff } final class MessageCustomKeyboard extends Message { // eg private $_keyboard; // constructor overrides parent public function __construct($chatId, $text, array $keyboard) { parent::__construct($chatId, $text); $this->setKeyboard($keyboard); } // ... stuff } $message = new Message(1, "Hello World"); $messageCustomKeybaord = new MessageCustomKeyboard(2, "Hello again", array("a", "b")); 
+2
source

All Articles