重构心路历程:如何做好抽象与设计?

自“重构”一词被Martin Fowler在上世纪末提出以来,一直受到诸多软件开发人员的追捧,圈内人若是对重构不大关注,似乎是有些数典忘祖的意味。于是乎,圈内人无论自身水平如何都开始关注重构,开始动手“去做”;至于做得好不好,结果合理与否,很难有事实标准去衡量。

越来越多的“网红重构”

Martin Fowler在写《重构》一书时,明确提出了重构的几个目的:

  • 改进设计
  • 使得软件更易被人理解
  • Find Bugs
  • 提高开发速度

可见重构的起点很明确--改进设计,OOP的出现为“软件设计“赋予了更深层的定义:”高内聚、低耦合“无人不知,无人不晓,可以被用于很多领域的设计工作上;然而对SOLID理解透彻的软件从业人员又有几何?

重构不是一时冲动,也不是为了达成特定的业绩目标。我更希望它能够成为软件从业人员自身的基本素质,不必时时刻刻挂在嘴边。重构的特殊性使得其价值体现有很长的延迟,只有出于本能的重构才是纯洁的,如果带有任何利益相关的目的性,那么这个重构就是有污点的。

如何改进设计?

业务是根本。不论是多复杂的软件,其根本目的都是为了实现人的业务需求,因此软件世界与真实世界有很多的相似性。关键过程就在于,我们如何把人的需求翻译成软件模型呢?

UML的出现为软件设计领域提供了事实标准,我们开始了解到了参与软件系统的一些关键角色;以及这些角色的依赖关系,甚至开始关注这些角色的状态变更。于是我们发现“抽象”极其重要,对于一个经常变化的业务需求,我们需要关注这些要点:

  • 基本流程和处理步骤是什么?
  • 有哪些关键角色参与了这个流程?
  • 这些角色自身有什么特点(属性)?
  • 这些角色是如何协同、合作(依赖、组合...关系)的呢?
  • 角色是否会发生状态变化(状态图)?

弄清楚了以上的内容,就可以按照UML标准给出一系列的设计图,用于说明你的设计意图(此处不建议其他的表达形式,鉴于UML已经足够成熟和被认可),但这个设计意图并不一定是最优解。

抽象与模式

OOP的魅力就在于抽象与复用,抽象其本质是分离稳定不变的点,而复用则是为了应付软件系统的复杂性,提供足够的灵活性来扩展软件系统。任何软件系统与真实世界必然存在联系,我们不妨先脱离软件设计本身的理论,仅考虑真实世界的类似场景,看看这个场景中存在哪些不变的参与者。

例如,我们在超市购物时,通常会有这样的场景:找到一辆购物车->选购商品->往收银台结算->付款打印小票。对应的,如果将这套业务搬到软件系统中,我们就会发现一些稳定出现的参与者:顾客(Customer),购物车(ShoppingCart),商品(Product),订单(Order),交易(Transaction),小票(Receipt)。
再深入探究一下这些参与者的行为特征:顾客通常会找购物车,会浏览商品信息选择是否购买,结账时支付订单;购物车就比较单纯,只负责装添加的货物;商品能够展示价格和基本信息;顾客推购物车去结算的时候会产生订单,结算时就完成了一笔或多笔交易,交易完成以后顾客就拿到了小票。把这些参与者的行为特征(业务方法)和自身属性组合起来,我们就有了软件系统中对应的一个角色,通常我们把它称之为“领域对象”(Domain Object)。

完成抽象之后,进一步关注这些领域对象之间的协同合作关系,此时我们就可以用上GOF的几十种设计模式(足够应付大多数场景)了。

更为一般的设计方法

并不是所有的场景都能非常明确地表明有多少参与者,这通常由业务需求在初期不明确且实现时缺少设计导致的,且大多数重构都是在这种场景下开展的。

IPO,即Input-Process-Output,对应于软件系统中的输入、处理和输出。对于已经识别的重构场景,不妨先关注这三个点:

  • 输入,这些输入有什么共同特点,是怎么被构建的呢?
  • 处理,对输入做了什么处理呢?产生了多少个中间角色?一共有多少角色参与?这些角色又是怎么联系起来的呢?
  • 输出,处理完成之后,软件系统输出了什么?系统其它模块对这个输出如何使用?

关注输入,可以提取到软件系统中关键的数据模型,针对其构建特点通常可以引入“构建型设计模式”;
关注处理和输出,可以更清晰地找到关键的参与角色,引入合理的“结构型模式”来规范这些角色之间的交互方式;如果能把这些角色的行为再进行组织和分析,通常“行为型模式”就可以被引入了。

什么是重构?

《重构》一书的推出,使得我们越来越关注所谓的代码坏味道,出现这些坏味道的根本原因就在于软件系统的抽象与设计不合理。如果只是识别了这些坏味道,把书中的手段一一应用,似乎很难让人信服这是一次完整的重构。所谓的“网红重构”,大抵如此吧。

总之,任何不关注改善设计和解读设计意图的重构都是鸡肋。

注:

  • UML:Unified Modeling Language,一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。
  • 领域对象:领域驱动设计的关键术语
  • GOF设计模式:Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides合著的《Design Patterns: Elements of Reusable Object-Oriented Software》
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352