【问题标题】:Call a method on a class or pass as a parameter to another class? C#在类上调用方法或作为参数传递给另一个类? C#
【发布时间】:2010-12-21 04:41:30
【问题描述】:

假设我正在使用“作业”类记录一些数据。 (具有各种属性的业务对象列表,物有所值。)

我希望能够打印这些数据,所以我想知道是否有更优选的设计来执行此操作。目前我有两个想法 - 在 Job 本身上调用 Print() 方法,或者将 Job 实例传递给某种打印控制器类,例如:

job.Print();

PrintWidget pw = new PrintWidget(job);
pw.Print();

目前,除了此 Job 类的数据之外,我无法想象打印任何其他内容。然而,谁知道未来会怎样。考虑到这一点,最好在我想打印的任何类上使用单独的 Print() 方法,还是使用一个可以处理不同类型的打印内容的 Print 控制器类?

你会如何设计这个?提前感谢您的任何回答。

【问题讨论】:

    标签: c# winforms oop printing


    【解决方案1】:

    您的问题完全符合 单一责任原则 (SRP),这是 SOLID 原则之一。

    该原则本质上表明,一个设计良好的组件应该只负责一项任务。另一种看待它的方式是组件应该只有一个改变的理由。这确保当您需要更改某些内容时,您知道所有功能都将在一个地方并且不会与其他功能混合

    在您的情况下,Job 可能具有打印以外的某种功能,也许是在您的域模型中代表“工作”的一些职责。如果是这样,那么您不想在此处添加打印功能。而是创建您的打印小部件并将所有打印逻辑放在那里。

    如果您的打印必须更改,您不必触摸您的Job 对象,因为它的职责没有改变。同样,如果“作业”的概念发生变化,则仅修改 Job 类并且打印不受影响(除非您现在有额外的内容要打印)。

    不过……

    如果Job 类的唯一 目的是表示一些打印信息,那么它绝对应该 包含PrintTo(Printer) 方法,其中@987654327 @ 将负责与物理打印机对话。在这种情况下,责任已转移到 Job 只参与打印,它应该控制它的打印方式。

    SRP 可能是您的设计中难以看到的模式,但有一种简单的方法可以确定:

    如果你能总结出 你的班级不使用这个词 "and",该类有一个 责任。

    所以,Job 要么负责“代表作业”,要么负责“打印作业信息”,但不能同时负责。

    【讨论】:

      【解决方案2】:

      一种选择是使用在 C# 3.0 中引入的Extension Methods。扩展方法允许您在不派生类的情况下扩展类,从而提供更大的灵活性。使用扩展方法,您可以将 Print 方法添加到 Job 类和任何其他类,而无需更改原始类。例如:

      static class PrintExtensions
      {
          public static void Print (this Job job)
          {
              // TODO: print Job
          }
      
          public static void Print (this SomeOtherClass c)
          {
              // TODO: print SomeOtherClass
          }
      }
      

      一旦你定义了一个扩展方法,你就可以像在类本身上定义它一样使用它,例如:

      Job job = GetJob();
      job.Print(); // call PrintExtensions.Print(this Job job)
      

      【讨论】:

        【解决方案3】:

        打印知识是Job 课程的关键部分吗?如果不是,它可能不应该在那个类中(关注点分离等)。如果打印在不同的上下文中可能有所不同,则这一点会加倍适用。我可能会做更多类似的事情:

        PrintWidget pw = new JobPrintWidget(); // perhaps via abstract-factory
        pw.Print(job);
        

        至于PrintWidget是什么...如果你将来需要支持其他类型,我猜你可能有一个抽象基类的具体实现(如上所示,其中Print是抽象方法),或替代接口。

        对我来说,这项工作更像是输入,但如果小部件只需要打印 1 个工作,那就这样吧。

        另一种可能性(在 C# 3 中)是扩展方法:

        static class PrintUtil {
            public static void Print(this Job job) {...}
        }
        

        允许您使用job.Print(),但无需将代码放入Job

        【讨论】:

        • Job 的主要功能主要是将其包含的数据保存到文件中,并显示出来。我预计实际打印它会很少见。
        • 听起来最好将“我是一份工作”和“我打印一份工作”逻辑分开,然后.
        【解决方案4】:

        就个人而言,我会将 Print 方法放在 Job 类中。如果您创建一个单独的 PrintWidget 类,则它必须了解有关 Job 类的所有信息。无论如何,如果您将来确实需要或想要一个 PrintWidget,您可以随时创建它并将 Job 类的 Print 方法重构为它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-10-18
          • 2023-01-18
          • 2020-03-14
          • 2013-10-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多