c# - (很多)内部方法是可以避免的吗? (接口(interface)、工厂模式)

标签 c# interface factory-pattern redundancy internal-class

我目前正在开发一个机器人,并且有大约 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/

相关文章:

c# - 运行 WPF 应用程序时出错

android - 找不到 JNI 方法

c++ - 具有抽象参数的抽象工厂?

泛型类的 Java 工厂

oop - 为什么 Haskell 不需要工厂模式?以及在 Haskell 中,OOP 中的模式解决的需求是如何解决的?

c# - 我是否需要同时安装 64 位 * 和 * x86 版本的 .Net SP2?

c# - 合并参数和 IList<T> 构造函数

c# - Fluent 验证在第一次失败后停止

java - 银行类OOP接口(interface)决定

module - SWI-Prolog 中的跨模块 "interface"调用