代码之家  ›  专栏  ›  技术社区  ›  srmark

为什么域驱动的设计似乎只在C#&Java这样的静态语言中流行?[关闭]

  •  32
  • srmark  · 技术社区  · 14 年前

    领域驱动的设计已经成为我选择的架构。我在ASP.net框架中找到了大量应用DDD原理的书籍和教程。它的灵感主要来自Java开发人员已经做了很长一段时间的工作。

    对于我的个人项目,我开始更倾向于Python,尽管我发现很难放弃静态类型。我希望能在使用动态语言应用DDD方面找到很多帮助。Python&DDD似乎什么都没有。为什么?显然,DDD可以很好地应用于Python。在Python中,人们不承担那么大的项目吗?或者,考虑到动态类型,在Python中应用DDD是否更容易,从而减少了所需的学习量?

    也许我的疑问是因为我缺乏使用Python的经验。如果你能给我提些建议,我将不胜感激。

    6 回复  |  直到 6 年前
        1
  •  15
  •   George Mauer    14 年前

    我认为它在其他地方肯定很流行,特别是函数式语言。然而,与大型蓝皮书相关的某些模式在动态语言中并不适用,像Rails这样的框架往往会让人们远离有限上下文的概念

    然而,在动态语言中,DDD是无处不在的语言的真正主旨无疑是普遍存在的。rubyist特别喜欢构建领域特定语言——想想cucumber特性最终会是什么样子,那就是DDD了!

    请记住,DDD根本不是一个新的想法,它只是重新包装的方式,得到了C#和Java的良好吸收。同样的想法在其他地方也有不同的标语。

        2
  •  8
  •   valignatev    8 年前

    这个问题困扰了我很长一段时间,所以我决定收集关于这个话题的所有有价值的数据。最后我以 this github repo .

    还有一些代码示例:

    (一) On Django

    2个) On Flask

    三) On Ruby

    还有一些。但绝对不够。

        3
  •  8
  •   fabriciorissetto    5 年前

    我认为用动态语言编写好的DDD项目是完全可能的,但是比用静态语言更难维护。为什么?

    工装

    对于静态类型的laguages,工具通常更强大。这就是为什么有些人使用 TypeScript 而不是普通的 JS ,因为它可以帮助您通过简化重构来扩展代码。当你维护一个DDD代码的时候,重构总是会出现的,因为业务有时会发生变化,你对模型的知识每天都在进化,有了这些知识,你的代码也必须进化。我的大部分经验都是在C#工作,我用它建立了很多DDD项目。现在我在一个用Ruby编写的DDD项目中工作,我最怀念的是缺少一个强大的IDE。在Ruby或Python中,人们习惯于使用文本编辑器,而不是IDE。我很难看到人们编写一些IDE或文本编辑器应该为我编写的东西(即缺少 自动完成 ). 很难看到人们在Vim中搜索一个文件的完整路径,只需打开它,在VS代码或Visual Studio中查看一个方法或类的详细信息,例如,一次点击 F12 应该足够 转到定义 类或方法,没有文件歧义。我都没说 调试经验 ,看到有人在写我很伤心 binding.pry (对于非ruby开发人员来说,这有点像js中的“debugger”关键字)在他们的代码中只是为了在终端中调试它,而不是仅仅在行上设置一个断点。这个列表比这个更大,但我认为它足以说明“工具”的意义。

    面向对象的表现力

    在一些动态语言(如Python和Ruby)中,您没有所有的OOP特性,如接口和 abstract classes . 这有时会给代码的表达和清晰带来一些困难。

    单元测试

    您需要编写更多的单元测试来代替编译器可以为您做的事情。

    动态键入

    你需要使用 duck typing 如果你想做一些类型检查。没有编译器的帮助。

    动态类型语言的优点

    免于典型化地狱

    在选择OOP动态语言和静态语言时,总是有折衷的办法。 在静态类型语言(如C#和Java)中,一个常见的问题是,有时类型系统会使代码难以表达,而且过于冗长。一些开发商倾向于 generics typification hell . 但并不是所有的静态类型语言都有这个问题(F是其中之一——因为强类型推理)。

    测试

    不使用静态类型在某些情况下也有帮助,例如,当您不想创建一个接口来注入您的类并使其可测试时。在这些情况下,接口对可读性没有帮助,事实上它损害了可读性,因为您需要创建一个哑文件(接口),它不代表除了测试代码之外的任何东西。在Ruby中,您可以通过多种方式来实现这一点,而无需创建接口,例如:

    class DispatchOrderService
      def initialize(overrides = {})
        @repository = overrides.fetch(:repository) do
          ::Infra::OrderRepository.new
        end
    
        @mail_service = overrides.fetch(:mail_service) do
          ::Infra::MailService.new
        end
      end
    
      def dispatch(order)
        order.dispatched
        repository.save(order)
        mail_service.notify_order_dispatched(order)
      end
    end
    

    是的,用这种方法我们打破了 clean architecture 因为类知道具体的“infra”实现。但是这是一个可以通过依赖注入来解决的问题(在Ruby中,这些框架总是破坏干净的架构,或者对于想要使用它的人来说太难看了,在我们的项目中,我们通过实例化依赖项来实现我们自己的DI容器 手动 在项目启动时)。

    结论

    最后,我认为用Ruby编写好的“企业”DDD应用程序是可能的,即使它比用静态语言编写困难。我目前的项目就是一个例子(6万行代码,仍然可以维护)。

    同时,@GeorgeMaueris提到的这一点也很重要。在框架中实现DDD可能会遇到一些问题,这些问题会使您无法组织代码。在这里我们选择使用 Hanami 而不是因为这个原因,但即使是Hanami也更“固执己见”,这是我们想要的。我真的不建议任何人去寻找构建DDD的“框架”。设计/架构从一个应用程序到另一个应用程序发生变化,并且不断发展。当您选择“DDD”框架时,有时您会面临与之抗争的情况(做一些变通方法或猴子补丁)。

    所以,也许你可以问我为什么我们选择ruby。在这里使用Ruby的要点是,几乎100%的团队都是由Ruby开发人员组成的,我们不想重复这些困难:学习DDD+一种新的编程语言。比单纯的技术决定更具战略性。这家公司(一家初创公司)如果没有它,可能不会走到今天。

    编辑2018:

    对于依赖DDD方面的项目,我们放弃了Ruby和Python。现在我们正在使用科特林,非常满意。主要的好处如下:

    • IntelliJ的最佳IDE支持。这使得我们在重构方面更快,在编译时会出现错误,并且在编写编译器可以为我们做的事情的测试时会更少。
    • 好的和流行的依赖注入框架,ORMs, functional programming
    • 语言本身的另一个好处(空安全、数据类等)

    编辑2019:

    我们写了一系列关于从Ruby到Kotlin的文章。你可以看到它 here .

        4
  •  3
  •   Mansouri    8 年前

    与Java相比,Python在企业中似乎还不太受欢迎(但我相信风向是这样的)。Django就是一个例子,它是由一家报纸公司创建的。大多数使用python的程序员可能要么从事科学计算,要么从事web应用。这两个领域都涉及(计算机)科学,而不是特定领域的业务,而DDD最适用于特定领域的业务。

    所以我认为这主要是一个遗产问题。C#和Java从一开始就面向企业应用程序。

        5
  •  2
  •   Dave Kirby    14 年前

    大多数关于设计/编码技术(如TDD和设计模式)的书籍都是用Java或C#编写的,因为这是目前最小的公分母语言,拥有最广泛的用户群,或者至少是能够阅读和理解该语言的最大用户群。这在很大程度上是出于市场营销的原因,以便吸引最大的人口。

    这并不意味着这些技术不适用于其他语言或在其他语言中使用。据我对DDD的了解,大多数原则都是独立于语言的,而最初的DDD书籍几乎没有代码样本(但我已经读了几年了,所以我可能弄错了)。

        6
  •  1
  •   asthasr    14 年前

    如果领域驱动的设计是一个有效定义的设计模式,为什么你使用的是什么语言很重要?对设计哲学等的建议在很大程度上应该是语言不可知的。可以说,他们比语言水平高。