4

在编写 GUI 应用程序时,我使用“控制”或“协调”应用程序的顶级类。顶级类将负责协调诸如初始化网络连接、处理应用程序范围的 UI 操作、加载配置文件等事情。

在 GUI 应用程序的某些阶段,控件被移交给不同的类,例如,一旦用户进行身份验证,主控件就会从登录屏幕切换到数据输入屏幕。不同的类需要使用顶层控件所拥有的对象的功能。过去我会简单地将对象传递给从属控件或创建一个界面。最近我已经改为传递方法委托而不是整个对象,主要原因有两个:

  • 单元测试时模拟方法比模拟类容易得多,
  • 它通过在类构造函数中准确记录下级类正在使用哪些方法,使代码更具可读性。

一些简化的示例代码如下:

delegate bool LoginDelegate(string username, string password);
delegate void UpdateDataDelegate(BizData data);
delegate void PrintDataDelegate(BizData data);

class MainScreen {
    private MyNetwork m_network;
    private MyPrinter m_printer;

    private LoginScreen m_loginScreen;
    private DataEntryScreen m_dataEntryScreen;

    public MainScreen() {
        m_network = new Network();
        m_printer = new Printer();

        m_loginScreen = new LoginScreen(m_network.Login);
        m_dataEntryScreen = new DataEntryScreen(m_network.Update, m_printer.Print);
    }
}

class LoginScreen {
    LoginDelegate Login_External;

    public LoginScreen(LoginDelegate login) {
        Login_External = login
    }
}

class DataEntryScreen {
    UpdateDataDelegate UpdateData_External;
    PrintDataDelegate PrintData_External;

    public DataEntryScreen(UpdateDataDelegate updateData, PrintDataDelegate printData) {
        UpdateData_External = updateData;
        PrintData_External = printData;
    }
}

我的问题是,虽然我更喜欢这种方法,而且这对我来说很有意义,但下一个开发人员如何找到它?在示例和开源 C# 代码中,接口是解耦的首选方法,而这种使用委托的方法更倾向于函数式编程。我是否可能让后续开发人员低声咒骂什么是违反直觉的方法?

4

2 回答 2

2

这是一个有趣的方法。您可能需要注意两件事:

  1. 就像 Philip 提到的,当你有很多方法要定义时,你最终会得到一个大的构造函数。这将导致类之间的深度耦合。多一位或少一位代表将要求每个人修改签名。您应该考虑将它们设为公共属性并使用一些 DI 框架。

  2. 有时将实现分解到方法级别可能过于细化。使用类/接口,您可以按域/功能对方法进行分组。如果您将它们替换为代表,它们可能会混淆并变得难以阅读/维护。

代表人数似乎是这里的一个重要因素。

于 2009-05-19T02:43:23.737 回答
1

虽然我当然可以看到使用委托而不是接口的积极方面,但我不得不不同意你的两个要点:

  • “在单元测试时模拟一个方法比模拟一个类要容易得多”。大多数 c# 的模拟框架都是围绕模拟类型的想法构建的。虽然许多可以模拟方法,但示例和文档(和焦点)通常围绕类型。用一种方法模拟接口与模拟方法一样容易或更容易。

  • “它通过在类构造函数中准确记录下级类正在使用哪些方法,使代码更具可读性。” 也有它的缺点——一旦一个类需要多个方法,构造函数就会变大;并且一旦从属类需要新的属性或方法,而不仅仅是修改接口,您还必须将其添加到链上的所有类构造函数中。

我并不是说这是一种不好的方法——传递函数而不是类型确实清楚地说明了你在做什么,并且可以降低你的对象模型的复杂性。但是,在 c# 中,您的下一个开发人员可能会认为这很奇怪或令人困惑(取决于技能水平)。将 OO 和函数式方法混合使用可能至少会引起与您合作的大多数开发人员的注意。

于 2009-05-19T02:17:36.753 回答