gpt4 book ai didi

php - 工厂设计模式实现疑惑

转载 作者:可可西里 更新时间:2023-11-01 13:20:50 24 4
gpt4 key购买 nike

我正在尝试为 Telegram Messenger 创建一个机器人,同时尝试学习 OOP。我真的不知道如何解决这个问题。我有一个 Message 实体,带有所有的 getter 和 setter,我认为这非常简单。我的问题是我想创建两种(或更多)类型的工厂

1)一个简单消息,您只需向工厂提供您要发送消息的 chat_id 和文本,它可能是这样的:

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

MessageAbstract 在哪里

<?php

namespace Telegram\Domain\Factory;

abstract class MessageAbstract {
abstract public function createMessage($chat_id, $text);
}

2) 带键盘的消息(Telegram 让您可以在发送消息时包含自定义键盘)。我这里有问题,键盘是作为数组给出的,所以这将是 createMessage 的另一个参数。

所以我的问题是,无论是简单消息还是带键盘的消息,我都应该始终给 $keyboard 参数吗?或者这两种类型的消息是否足够不同,以至于它们应该从不同的类创建(我认为不是)?或者也许我不应该在工厂里做,而应该用 setter 和 getter?

TLDR:如何以奇特的方式创建具有不同数量参数的对象,就像这样

$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?

最佳答案

我同意 @CD001 关于子类型化/扩展的观点,所以我不会重复他的回答,但您仍然可以通过使用依赖注入(inject)识别所需类型并返回适当的对象来使用工厂模式。

您可以为工厂方法的这种依赖项包含一个专用参数,或者您可以使用方法重载来注入(inject)它并只检查那些特定类型(如果在指定的两个之外可能返回其他类) .

坚持使用工厂模式确实可以帮助您在不做太多额外工作的情况下扩展它,现在偷工减料只会导致以后的痛苦。


编辑:

注入(inject) (注意:我包含了一个类型参数来涵盖一种可能的字符串扩展技术,但这也可以很容易地成为一个注入(inject)类型对象,这取决于您. 还包括为消息构造函数同时注入(inject) Message 属性的选项,因此您会得到一个完全实例化的对象,而不是一个空的 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;
}
}

这样,您所有的 Message 对象都可以使用相同的界面,可以使用自定义或基本键盘,并且可以轻松扩展。您当然可以扩展 $attributes 并在实例化后使用您的个人 setter ,或者如果您有很多 setter ,则在构造函数中循环使用它们。我个人不喜欢构造函数中有大量参数,而宁愿遍历可选参数数组。

关于php - 工厂设计模式实现疑惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33739217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com