我目前正在开发一个机器人,并且有大约 8 个用于不同对话框的独立类(全部位于同一命名空间中!)。它们都包含不同的任务,因此我遇到了一个小问题。 我想知道最佳实践是什么:使用接口(interface)、使用工厂模式……然而,所有这些选项都迫使我使用内部方法。 (我通过接口(interface)得到了这一点,因为你 promise 了某些行为,但对于工厂模式,我真的不知道 - 说实话......)因为没有特定方法的定义 - 但这意味着我必须做出很多这些内部方法,我试图避免冗余。
首先,我刚刚实例化了一个新对象,但我很快意识到这意味着每次调用机器人时都会创建每种类型/对话框的新对象 - 这不是很有效,对吧?我还尝试在构造函数中实例化它们,但这迫使我使用接口(interface),这给我带来了与我之前所说的相同的问题。我也研究过部分类,但我不确定使用 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 { … }
}
我尝试在主方法中访问 AddNameResponse 任务,如下所示: await dial.CreateDialog("name").AddNameResponse(turnContext, profile, value);
这不被接受,但是给了我以下警告:“DialogFactory”不包含“AddNameResponse”的定义,并且没有可访问的扩展方法“AddNameResponse”接受“DialogFactory”的第一个参数。修复将是一个内部任务,但我试图避免这种情况(之前给出的原因)。
我在这里真的很茫然,因为我不知道最好的做法是什么。我正在尝试制作最高效、最干净的代码,并避免冗余并使用尽可能多的松散耦合 - 但我不知道如何在这种情况下实现这一点...... 我希望我已经足够好地阐述了我的问题(以及问题)!
最佳答案
工厂模式对于多态性来说是有意义的。这意味着,例如,我们想要一个 IDialog
并且我们不关心实现是什么。我们不想知道。这样我们的代码依赖于 IDialog
并且不耦合到任何实现它的特定类。
如果您尝试执行此操作:
dialog.CreateDialog("name").AddNameResponse(turnContext, profile, value);
...错误是从 dialog.CreateDialog("name")
返回的任何内容都没有 AddNameResponse
方法,这表明您的代码取决于一些比工厂返回的更具体的类。
工厂不会减少耦合有几个原因:
- 您的代码仍然依赖于
NameDialog
。您需要该确切的类及其AddNameResponse
方法。 - 即使工厂返回了确切的类,现在您也已耦合到工厂和该类。
您希望减少耦合是有道理的,因为如果一个类与 NameDialog
绑定(bind),那么它也与 ProfileService
绑定(bind)。如果不依赖于 ProfileService
,就不可能测试依赖于 NameDialog
的类。
潜在的解决方案将涉及更改依赖于NameDialog
的类。以下是一些想法:
- 定义一个抽象(例如接口(interface)或委托(delegate))来描述您的类需要使用
NameDialog
执行哪些操作。将其注入(inject)到你的类中。现在你的类依赖于抽象,而不是具体的类。 - 如果
NameDialog
做了一些非常简单的事情,也许您可以注入(inject)它而不是抽象,更好的解决方法是定义一个代表ProfileService
的抽象并将其注入(inject)到名称对话框
。 - 可能两者都做。
这些的意思是你是
- 通过依赖抽象来避免耦合
- 让依赖注入(inject)/IoC 容器负责创建对象
这比将所有这些对象的创建合并到一个工厂中效果更好。仅当工厂返回的任何对象可替代任何其他类型时,这种方法才有意义 - 您不需要知 Prop 体类型是什么。
关于c# - (很多)内部方法是可以避免的吗? (接口(interface)、工厂模式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56217280/