使用C#或其他语言的Scala风格的抽象模块? - c#

我正在阅读马丁·奥德斯基(Martin Odersky)的《 Scala中的编程》一书,其中涉及抽象模块,以及他的论文《可伸缩组件抽象》:

http://lampwww.epfl.ch/~odersky/papers/ScalableComponent.pdf

我的收获是,通过使模块成为抽象类而不是对象(或经典的静态全局模块(如Java)):

abstract class myModule{ 
    // this is effectively an abstract module, whose concrete 
    // components can be configured by subclassing and instantiating it
    class thing{}
    class item{}
    object stuff{}
    class element{}
    object utils{}
}

您可以实例化具有不同具体特征的模块的多个子类和实例。这使您可以根据情况(例如,在测试期间替换数据库组件或在开发环境中时使用IO组件)不同地配置模块,以及实例化多个模块,每个模块都具有自己的一组模块作用域可变状态。

据我了解,从根本上来说,唯一的困难是您可以拥有嵌套类,以便封闭类可以充当模块。

另一个实际要求是您可以将类定义散布到多个文件中,因为其中包含一堆类的模块的代码行可能比大多数在单个源文件中接受的代码行多。

Scala通过Traits做到了这一点,它带来了一些其他优点,这些优点虽然不错,但对于整个跨多个源文件的抽象模块类思想而言并不是很重要。 C#具有partial classes,它提供相同的功能,并且还允许嵌套类。大概其他语言也对嵌套类以及将类拆分为多个文件具有类似的支持。

这种模式会发生在C#或任何其他语言的任何地方吗?我认为用多种语言编写的大型项目都面临抽象模块要解决的问题。是否有任何理由将此“抽象类作为抽象模块”的东西不起作用,因此不被使用?在我看来,比提供相同功能的各种DI框架要干净得多的解决方案。

参考方案

您描述的抽象模块具有以下核心属性:

  • 这是一个封闭的模块,这意味着它提供了允许与模块
  • 进行交互的所有接口

  • 您可以在模块
  • 上指定操作

  • 您可以指定属于模块的类型-通常这些类型由上述模块操作
  • 没有提供实现-这是抽象部分:可以有许多具体的实现,并且程序中将实际指定实际使用的程序,因为它最适合
  • 能够使用多个源文件指定模块的功能不是核心要求,但肯定可以派上用场。

    模块以其最基本的形式描述一种抽象的数据类型(例如队列):哪些操作可用于与该数据类型进行交互,以及交互所需的任何辅助类型。

    它可以以更复杂的形式描述整个子系统(例如网络)。

    在命令式语言中,通常将接口用于相同目的:

  • 包含在内
  • 您可以指定操作
  • 您可以指定属于
  • 接口的一部分的类型

  • 没有实现
  • 如您所提到的,如果您的模块具有较大的接口(例如描述子系统),则通常无法在一个文件中编写实现富接口的类。如果该语言不支持将同一类拆分为单独的源(或更确切地说,是将“不同源文件中的”同一类的不同部分“粘合”在一起),则解决方案通常是丢失随附的要求并提供一系列定义接口之间的交互的接口-因此,您将获得子系统的API(这是最纯粹的API:它是与子系统交互的接口,尚无实现)。

    在某些方面,后一种方法可能比封闭的类型更通用(就您可以实现的意义而言是通用的):您可以提供不同作者的各种子类型(通过接口指定)的实现:子类型仅依赖于指定的接口进行相互交互,因此这种mix-n-match方法将起作用。

    参数化数据类型是大多数功能性编程语言的优势之一,您可以在其中实例化一个Dayatype,将另一个类型作为其参数(例如,整数队列)。 Java / C#中的泛型(和C++中的模板)实现了相同的灵活性。当然,根据语言的类型系统,确切的含义和表达能力可能会因语言而异。

    整个讨论是单独的形式的依赖注入(DI),它试图通过显式提供所需的部分(而不是让实现选择)来放松类型的具体实现及其支持部分之间的强依赖关系。该类型可能对这些部分的哪种实现最能实现其目标有更好的了解-例如提供用于测试功能的模拟实现。

    DI试图解决的问题是命令式语言所独有的,您也可能在功能语言中遇到相同的依赖项问题:抽象模块的实现可能选择使用子类型的特定实现(因此将自身耦合到这些实现)而不是以子类型的实现作为参数(这就是DI的目标)

    使用C#运行Java应用程序并从CMD获取其输出 - c#

    我想使用C#程序运行Java控制台应用程序并获取其输出。到目前为止,我很难用参数运行java.exe,在这种情况下,Im是要执行的.java文件的名称。假定已编译的Java控制台应用程序的名称为:JavaConsoleApplication提取时将显示“ hello world”,并且我还放置了一个JOptionPane MessageDialog,以确保它…

    使用C#构建的Android应用在真实设备上崩溃,但可在模拟器上运行 - c#

    我已经建立了一个android应用。我的应用程序可以在模拟器上运行,但是当我导出.apk文件并在真实设备上对其进行测试时,它立即崩溃。我已经尝试取消选中快速部署和共享运行时。我已经检查了互联网许可,因为我有一个webview。我使用的设备是android 5.0,并且该应用程序支持该设备。 参考方案 尝试调试设备中的应用程序并检查日志。这将帮助您找出实际的问…

    使用C#创建网页弹出窗口 - c#

    如何使用c#创建打开的网页作为弹出窗口,并且在关闭弹出窗口时需要运行一个函数。我的意图是在成功完成活动后创建Web登录/注销并运行功能 参考方案 好吧,您并没有付出太多,但是,如果我猜您的体系结构是ASP.NET,那么您应该在页面代码中的服务器上有事件可以处理该事件。如果您对自己的要求有所了解,我们可以为您提供更多帮助。仅出于完整性考虑,您应该知道您不能只在…

    Java:“自动装配”继承与依赖注入 - java

    Improve this question 我通常以常见的简单形式使用Spring框架: 控制器服务存储库通常,我会在CommonService类中放一个通用服务,并使所有其他服务扩展到类中。一个开发人员告诉我,最好在每个服务中插入CommonClass而不是使用继承。我的问题是,有一个方法比另一个更好吗? JVM或性能是否会受到另一个影响?更新资料Comm…

    使用C#在Linux服务器中检查文件是否已使用.Net Core更新 - c#

    我正在做一个.Net Core应用程序,需要检查某些文件最近是否被替换过。基本上检查文件是否被较新版本替换(它可能是同一文件或具有相同的大小,但是由于某种原因被替换了)。我今天在2020年3月4日下午12:32将文件上传到服务器,然后尝试使用File.GetLastWriteTime,但它给了我2019年2月27日,这可能是文件最初创建时或将文件下载到PC时…