演化架构和紧急设计: 利用可重用代码,第2部分

简介:在使用 演化架构和紧急设计 前几期描述的技术发现 代码中的紧急设计之后,下一步您需要一 种获取和利用这些设计元素的方法。本文介绍了两种用于获取惯用模式的方法:将模式作为 APIs 进行捕 捉;使用元程序设计方法。

本 系列 的前几期主要关注紧急设计中显而易见的第一步:发现 惯用模式。发现惯用模式之后,您要 用它做什么?该问题的答案就是本期重点,本文属于由多个部分组成的系列文章的第二部分。第 1 部分 —代码与设计的关系探讨— 介绍了一种观点的理论基础,这种观点就是软件中的设计真正是指解决方案 的整个源代码。一旦转换角度将所有 代码当做实际设计,您可以开始考虑在语言级别巩固设计元素,而 非仅在图表范围和其他设计辅助项目中。在这里我要讲一下在发掘出代码中的可重用设计之后应该做些什 么,介绍获取这些模式所用的方法。我首先将它们作为简单 APIs 获取,然后描述一种可将这些元素与其 他代码区分开来的获取方法。

将模式作为 APIs 予以获取

捕捉惯用模式最简单的方式就是将它们作为自身的 API 或框架予以提取。您使用的大多数开源框架都 是与解决特定问题相关的惯用模式集。例如,Web 框架包含您构建 Web 应用程序所需的所有 API 元素, 它们预先从其他运行的 Web 应用程序中获得。例如,Spring 是用于处理依赖项注入和构建的技术惯用模 式集合,Hibernate 为对象-关系映射封装模式。

当然,您可以在您的代码中做同样的工作。这是目前为止最简单的方法,因为您改变的仅是代码的结 构(通常通过在您选择的 IDE 中重构支持)。这种方法的大量示例参见 第 1 部分 以及 “语言、表达 性与设计:第 2 部分”, 该部分探讨了设计模式。

避免结构重复

APIs 偶尔会促进结构重复。使用 APIs 会很烦人,因为您必须频繁使用主机对象来调用 API。下面来 看一下清单 1 中的示例(其中调用一个与有轨电车相关的 API):

清单 1. 访问 Car API

Car2 car = new CarImpl();
MarketingDescription desc = new MarketingDescriptionImpl();
desc.setType("Box");
desc.setSubType("Insulated");
desc.setAttribute("length", "50.5");
desc.setAttribute("ladder", "yes");
desc.setAttribute("lining type", "cork");
car.setDescription(desc);

强制用户输入主机对象(desc)会给代码增加不必要的干扰。大部分 APIs 包括主机对象并将其作为 API 的入口点,您必须携带它们才能访问 API。

目前有几个方法可缓减 APIs 中的这个问题。其中一种方法使用一个鲜为人知的 Java 语法,它允许 您通过一个匿名内部类的作用域界定 “携带” 主机对象,如清单 2 所示:

清单 2. 使用一个匿名内部类携带主机对象

MarketingDescription desc = new MarketingDescriptionImpl() {{
   setType("Box");
   setSubType("Insulated");
   setAttribute("length", "50.5");
   setAttribute("ladder", "yes");
   setAttribute("lining type", "cork");

}};

时间: 2024-12-24 21:15:05

演化架构和紧急设计: 利用可重用代码,第2部分的相关文章

演化架构和紧急设计:利用可重用代码,第1部分

简介:识别出代码中的惯用模式后,下一步是积累和使用它们.理解设计与代码之间的关系有利于发 现可重用的代码.本期的 演化架构与紧急设计 探索代码与设计的关系,使用表达性强的语言的重要性, 以及重新考虑抽象风格的潜在价值. 通过本 系列 的前几期,您已经知道,我的观点是软件的每个部分都包括可重用的代码块.例如,公 司处理安全性的方式在整个应用程序甚至多个应用程序中可能都是一致的.这就是我所说的 惯用模式 的 实例.这些模式代表对构建软件特定部分时遇到的问题的常用解决方案.惯用模式有两种类型: 技术模

演化架构与紧急设计: 积累惯用模式

简介: 本期将之前的 演化架构与紧急设计 文章中的紧急设计概念与一个案例研究相结合,展示如何 发现.积累和利用代码中意料之外的设计元素.一旦理解了如何识别设计元素,便可以使用该知识改进代 码的设计.紧急设计使您可以发现代码中意料之外但是已成为代码库重要部分的那些方面. 在本系列第一期 "研究架构和设计" 中,我曾断言每个较大的项目都包括超出所有人意料的设计元 素.详细考虑一个问题时,常常会发现有些本以为困难的事情实际上却更容易,有些本以为容易的事情实 际上却更困难.随后的几期则演示了发

演化架构与紧急设计:研究架构和设计

演化架构(evolutionary architecture)和紧急设计(emergent design)都是将 重要的决策推迟到最后责任时刻(Last Responsible Moment)的敏捷技术.在本 系列的第一期文章中,系列作者 Neal Ford 将定义架构和设计,然后指明了一些 关于整个系列的基本概念. 软件架构和设计一直都没有一个明确的定义,因为软件开发作为一门学科,尚 未完全理解其中的复杂度和内涵.但是要发表关于这些主题的论述,您必须从某 个位置开始.本系列涉及演化架构和紧急设

演化架构与紧急设计:对设计进行重构

在 "测试驱动设计,第 1 部分" 和 "测试驱动设计,第 2 部分" 中,我 介绍了测试如何为新的项目实现更好的设计.在 "组合方法和 SLAP" 中,我讨 论了两种关键模式 - 组合方法(composed method)和单一抽象层原理 - 为您 的代码结构提供了整体目标.需要牢记这些模式.一旦拥有了一个现有软件项目 ,那么发现和利用设计元素的主要方法就是进行重构.在 Martin Fowler 的经典 著作 Refactoring 中,他将

演化架构和紧急设计: 演化架构

简介: 这一期的 演化架构和紧急设计 将会解决演化架构相关的各种主题,包括设计和架构之间的重 要区别(以及如何区分两者),您在创建企业级架构时遇到的某些问题,以及面向服务的架构中静态类型 和动态类型的区别. 在 本系列的第一期 中,我推荐了软件世界中的一些架构定义.无论如何,如果您已经阅读过本系列 ,您会注意到我花费了大部分时间在设计上.我之所以这么做是基于以下几个原因:首先,在当前紧急设 计尚未被广泛关注时,软件世界里存在很多架构定义(良莠不齐):其次,在设计方面很多问题都有具体 的.不受环境

演化架构与紧急设计: 通过指标进行紧急设计

简介: 软件指标可以帮助您寻找代码中隐藏的设计元素,让它们能够成为惯用模式. 演化架构与紧急设计 的这一期讲解如何使用指标和可视化发现被复杂性掩盖的重要代码元素. 紧急设计的难题之一是寻找隐藏在代码中的惯用模式和其他设计元素.指标和可视化有助于识别代码的重要部分,从而提取出一些设计元素.本文主要讨论两个指标,圈复杂度(cyclomatic complexity) 和传入耦合(afferent coupling).圈复杂度度量方法的相对复杂度.传入耦合表示有多少个其他类使用当前类.本文要介绍显示和

演化架构和紧急设计: 使用 DSL

简介:至今, 演化构架和紧急设计 主要关注技术模式的紧急设计,本期将介绍使用特定领域语言 (DSL)捕获 领域惯用模式.系列作者 Neal Ford 用一个例子说明了该方法,显示了这种获取惯用模式 的抽象样式的优势. 惯用模式可以是 技术也可以是 领域.技术模式为常用的技术软件问题指出解决方案,例如在应用程 序(或应用程序套件)中怎样处理验证.安全和事务数据.前几期主要关注获取技术惯用模式所用的技术 ,例如元程序设计.域模式关注的是如何抽象常见业务问题.而技术模式几乎出现在所有的软件中,域模 式

演化架构与紧急设计: 组合方法和 SLAP

简介:如何在陈旧的代码库中找出隐藏的设计?本文讨论两种对于代码结构很重要的模式:组合方法 和单一抽象层.对代码应用这些原则有助于找到以前隐藏的可重用资产,有助于把现有的代码抽象为成熟的框架. 在这个 系列 的前两期中,我讨论了如何使用测试驱动开发 (TDD) 帮助您逐步发现设计.如果从头开始一个新项目,这种方法的效果非常 好.但是,更常见的情况是您手中已经有许多并不完善的代码,在这种情况下应该怎么办呢?如何在陈旧的代码库中找出可重用的资产和隐藏 的设计? 本文讨论两个很成熟的模式,它们可以帮助您

演化架构与紧急设计: 语言、表达性与设计

简介:发现和积累惯用模式的能力对于紧急设计至关重要.对于设计而言同样十分重要的是代码的表 达性.在本系列文章的第 2 部分中,Neal Ford 将继续讨论表达性和模式的交集,通过惯用模式和正式 设计模式阐释这些概念.他用动态语言为 JVM 重构了一些经典的四人组(Gang of Four)模式,以说明 表达性更好的语言如何使您看到被透明度不佳的语言遮挡的设计元素. 本文是本系列文章的第 2 部分,旨在演示计算机语言的表达性(允许您专注于本质,而不是形式)对 于紧急设计的重要作用.意图(inte