【发布时间】:2019-05-20 08:46:19
【问题描述】:
我目前正在开发一个机器人,并且有大约 8 个用于不同对话框的单独类(都在同一个命名空间中!)。它们都包含不同的任务,因此我遇到了一个小问题。 我想知道最佳实践是什么:使用接口,使用工厂模式……然而,所有这些选项都迫使我使用内部方法。 (我通过接口得到它,因为你承诺某些行为,但是对于工厂模式我真的不知道 - 老实说......)因为没有特定方法的定义 - 但这意味着我必须做出很多这些内部方法,我试图避免冗余。
首先我只是实例化了一个新对象,但我很快意识到这意味着每次调用机器人时都会创建一个各种类型/对话的新对象 - 这不是很有效,对吧?我也尝试在构造函数中实例化它们,但这迫使我使用接口,这给我带来了与我之前所说的相同的问题。我也研究了部分类,但我不确定使用 8 个部分类是否真的......好吗?
现在我正在使用以下代码尝试工厂模式: (此主题的致谢:How to prevent an instantiation of an object in c#)
public class DialogFactory
{
private NameDialog _nameDialog;
private CertificateDialog _certificateDialog;
private ProfileDialog _profileDialog;
private ClassDialog _classDialog;
private LocationDialog _locationDialog;
private SkillDialog _skillDialog;
private EducationDialog _educationDialog;
private SpecializationDialog _specializationDialog;
public DialogFactory CreateDialog(string dialog)
{
switch (dialog.ToLower())
{
case "name": return new NameDialog();
case "certificate": return new CertificateDialog();
case "profile": return new ProfileDialog();
case "class": return new ClassDialog();
case "location": return new LocationDialog();
case "skill": return new SkillDialog();
case "education": return new EducationDialog();
case "specialization": return new SpecializationDialog();
default: throw new Exception("That dialog does not exist.");
}
throw new Exception("That dialog does not exist.");
}
}
为了给出对话框看起来的一些上下文,我还将在此处添加名称对话框:
public class NameDialog : DialogFactory
{
ProfileService profileService = new ProfileService();
public async Task AddNameResponse(ITurnContext turnContext, Profile profile, string value { … }
}
我尝试在 main 方法中访问 AddNameResponse 任务,如下所示:await dialog.CreateDialog("name").AddNameResponse(turnContext, profile, value); 这不被接受,但是给了我以下警告:“DialogFactory”不包含“AddNameResponse”的定义,并且没有可访问的扩展方法“AddNameResponse” ' 接受 'DialogFactory' 的第一个参数。修复将是一个内部任务,但我试图避免这种情况(之前给出的原因)。
我真的很茫然,因为我不知道最佳做法是什么。我正在尝试制作我可以制作的最有效和最干净的代码,并避免冗余并尽可能多地使用松散耦合 - 但我不知道如何在这种情况下实现这一点...... 我希望我已经很好地阐述了我的问题(也是问题)!
【问题讨论】:
-
however, force me to use internal methods- 但为什么呢?对于具有name属性和show(dialogContext)方法的IDialog,这似乎是一个相当正常的用例?为什么你不这么认为? -
是否允许机器人同时打开多个对话实例?如果不是,那么是的,您可能希望实例成为单例以节省内存,但是,我不确定您为什么需要工厂来执行此操作。这些
Tasks 是否存在是因为 IO 是异步的(通过网络?)并且您需要等待对机器人的请求/响应?如果您想避免实例化 - 您可以创建一个静态类并通过该类使所有实例可访问您在调用CreateDialog方法时无法访问实例方法,因为您返回的是工厂本身而不是对话框实例...跨度> -
@MatJ 我也在想是的!但是因为 IDialog 也将用于所有其他对话框,这意味着我必须在这些对话框中创建内部类,因为使用接口时承诺的行为。这将导致其他 7 个内部任务,反之亦然,在我看来这不是很干净..
-
CreateDialog的返回类型是DialogFactory- 但这意味着所有对话框实例都将从DialogFactory继承,然后您将拥有FactoryCeption。这绝对是你的代码吗? -
如果您对应该呈现的对话框有足够的了解并且想要对其做出响应,那么通用 解决方案很可能不是正确的选择。为什么不能直接
new NameDialog().AddNameResponse(...)呢?
标签: c# interface factory-pattern redundancy internal-class