标签: 对象协作设计
控制反转容器和依赖注入模式
在 Java 社区,涌现出大量轻量级容器,它们有助于将来自不同项目的组件组装成一个 cohesive 的应用程序。这些容器底层有一个通用的模式,即它们如何执行连接,这个概念被称为“控制反转”。在本文中,我将深入探讨这种模式是如何工作的,它有一个更具体的名称叫做“依赖注入”,并将其与服务定位器进行对比。两者之间的选择并不重要,重要的是将配置与使用分离的原则。
集合管道
集合管道是一种编程模式,您可以在其中将某些计算组织为一系列操作,这些操作通过将集合作为一项操作的输出并将其馈送到下一项操作来组合。(常见操作是过滤、映射和 reduce。)这种模式在函数式编程中很常见,在具有 lambda 的面向对象语言中也很常见。本文通过几个如何形成管道的示例来描述该模式,既向不熟悉该模式的人介绍该模式,也帮助人们理解核心概念,以便他们可以更轻松地将想法从一种语言应用到另一种语言。
依赖组合
基于对传统的基于框架的依赖注入的失望,我采用了一种组合策略,利用部分应用程序将上下文注入模块。当与作为设计过程的测试驱动开发以及对函数优于类的关注相结合时,模块可以保持清晰、干净,并且基本上没有意外耦合。
重构:此类太大
在本文中,我将介绍来自真实代码库的一组重构。这并非旨在展示完美,而是代表现实。
重构访问外部服务的代码
当我编写处理外部服务的代码时,我发现将访问代码分离到单独的对象中很有价值。在这里,我将展示如何将一些凝结的代码重构为此分离的常见模式。
使用循环和集合管道进行重构
循环是处理集合的经典方式,但随着编程语言中对一流函数的更多采用,集合管道成为一种有吸引力的替代方案。在本文中,我将通过一系列小示例来介绍如何将循环重构为集合管道。
实践中的 DIP
依赖倒置原则 (DIP) 自 90 年代初就已出现,即使在解决问题的过程中似乎很容易被遗忘。在进行了一些定义之后,我将介绍我在实际项目中亲自使用过的 DIP 的许多应用,以便您有一些示例可以从中得出自己的结论。
DDD 聚合
聚合是领域驱动设计中的一种模式。DDD 聚合是可以视为单个单元的域对象集群。例如,订单及其订单项,这些将是单独的对象,但将订单(及其订单项)视为单个聚合很有用。
函数作为对象
在编程中,对象的根本概念是数据和行为的捆绑。这在编写一组相关函数时提供了一个通用的数据上下文。它还提供了一个操作数据的接口,允许对象控制对该数据的访问,从而可以轻松支持派生数据并防止对数据进行无效修改。许多语言都提供了定义类的显式语法,这些类充当对象的定义。但是,如果您使用的语言具有一流的函数和闭包,则可以使用这些构造来使用函数作为对象模式(最初由 Eugene Wallingford 描述)创建对象。
四人帮
在我看来,《设计模式》是有史以来关于面向对象设计的最佳书籍——可能是任何设计风格的最佳书籍。这本书对软件行业产生了巨大的影响——看看充斥着 GOF 模式的 Java 和 .NET 库就知道了。
Getter 终结者
当他们看到一个 getter 方法时,你可以通过他们嘴角左侧的抽搐来识别他们,他们迅速地拔出他们的战斧,发出一声满意的叫喊,因为另一个 getter 被无情地从一个类中砍了下来,这个类立即欣喜若狂地倒在了男子气概的 Getter 终结者的脚下。
接口实现对
采用每个类并将其与接口配对的做法。因此,您会看到成对的事物——可能是 ICustomer 和 Customer,或者 Customer 和 CustomerImpl。在许多方面,它反映了 C/C++ 为每个类使用头文件的习惯,尽管在这种情况下,接口和实现实际上是独立的类型。
控制反转
控制反转是您在扩展框架时遇到的常见现象。事实上,它通常被视为框架的一个定义特征。
延迟初始化
延迟初始化是一种在第一次访问时初始化变量(在 OO 上下文中通常是类的字段)的技术。它的规范形式如下所示
必需接口
必需接口是由交互的客户端定义的接口,它指定了供应商组件需要做什么才能在该交互中使用它。
告知,不要询问
告知,不要询问是一条原则,可以帮助人们记住面向对象是关于将数据与操作该数据的函数捆绑在一起。它提醒我们,与其向对象询问数据并根据该数据采取行动,不如告诉对象该做什么。这鼓励将行为移动到对象中以与数据一起使用。