思考如何做好架构设计

简介: 在开发软件中过程中,我们时常会遇到这样的场景:在需求描述中只要求我们提供一个针对其特定需求的功能,但是作为程序员,直觉告诉我们在别的场景下可能有类似的需求,但是这个“别”的场景还没有真正出现,处在可能出现,也可能不会出现的境地,那我们应该如何应对这样的情况呢?在这篇文章中,将对如何处理这样的问题进行探讨。 在展开探讨前,我们先定义如下的两个词汇,便于我们后面的讨论:通用:是指在设计中考虑了多个不同的使用场景,能在多个不同的场景下提供服务特定:只考虑很特定的场景,要求在相对较多的限制条件下才能提供服务

对比


  大家都知道在软件开发中不存在银弹,所以在业务开发中,到底是使用“通用设计”,还是使用“特定设计”并没有一个确切的结论。在这里我们先对比一下二者的优劣。


特定场景


  优点:一般是针对一个特定场景,这样设计难度会相对较低,特定场景下的使用者在也很明确如何使用,降低了其认知负担,从而也保证了能业务能尽快上线  缺点:一旦使用场景发生了一些变化,可能需要重新投入人力来进行开发


通用场景


  优点:当使用场景发生了,如果在通用设计已经考虑的范围内,这不需要进行重新设计  缺点:设计时难度相对较大,并且可能会陷入过度设计的泥潭中,并且由于业务的变化,在设计时所做的假设并不一定会发生


小结


  在上面的对比中,可以看到二者各有优劣,而在现在的软件设计中,我们时常会提到“简单、合适和演进”的设计原则,在简单原则下我们应该采用特定设计,但是合适和演进的原则则会鼓励我们多采用通用设计;同时,这个原则也暗示我们要将特定设计和通用设计结合起来,只有这样才能真正的做到“简单、合适和演进”


融合


  在如今绝大部分开发中,我们都会采用模块化的开发方式,这里的模块可以是 包,类,服务等。而模块的自身组成可以分成接口和实现两个部分。在接口部分,主要表达了模块能做什么,而在实现部分则是模块如何做。而模块的接口和实现,则分别为施展“通用设计”和“特定设计”提供场所。


通用


  模块的接口部分主要是体现模块能提供的能力,及能做什么。在软件的开发中,有两大难题:一个复杂,另外一个变化,但是归根到底还是复杂。而复杂有三个具体的表现:


  • 变化导致很多模块的修改
  • 增加开发人员认知负担
  • 导致发生不可预知的问题

而在模块的接口设计中充分考虑“通用设计”,恰好能减缓这三种表现,具体如下:


  1. 在模块的接口设计中充分考虑“通用设计”,对外部的调用者需要屏蔽其模块的内部实现,这样在内部实现发生变化时,就不会导致调用者的修改


  1. 在模块的接口设计中充分考虑“通用设计”,在多种情况下调用者只需要掌握相同的方法就能处理,降低认知负担


  1. 在模块的接口设计中充分考虑“通用设计”,通过少数几个方法提供模块的能力,不需要接触内部负复杂的实现,提升明确性


  另外,在模块的接口设计中充分考虑“通用设计”,也让设计人员能充分考虑模块的战略价值,保证了模块的持续演进


特定


  模块的实现部分则是体现了如何做,而软件之所以有价值,其根本原因就是因为其完成了特定的工作,而“特定设计”恰好符合这样的需求;而在整个软件的生命周期中,发生变化是不可避免的,如果我们在模块的实现部分考虑过多,往往就会掉入过度设计的陷阱,也不符合我们谈到的“简单”设计的原则


设计


  在模块的接口和实现部分分别采用了“通用”和“特定”后,在接口的“通用设计”部分容易发生两类问题:


  • 通用性不足,接口的设计不能满足后续演进的需要
  • 过犹不及,接口的设计太复杂,增加使用者的认知负担


  为了避免这样的问题的出现,根据我自己的经验提供三个可以自问自答的问题,供大家在设计时进行考虑:


当前的接口设计是否满足当前的需要?


  这个问题的意义在于保证了当前模块对业务提供的足够的价值


满足我当前所有需求的最简单的接口什么?


  这个问题的意义在于可以控制接口方法的总数,通过提供较少的接口,就能需求,从而提升了接口的通用性


接口方法有多少场景会被使用?


  这个问题的意义在于促使我们考虑接口的通用性是否足够


目录
相关文章
|
5月前
|
存储 关系型数据库 BI
数据架构是什么?数据架构有几个层次?
本文通俗解析企业数据架构五大核心层次:数据源(起点)、存储(仓库)、处理(厨房)、服务(快递站)、应用(餐桌),厘清每层职责、技术选型与协同逻辑,助企业摆脱数据混乱困局,构建可演进、易维护的数据管理体系。
|
存储 关系型数据库 分布式数据库
6倍性能差100TB容量,阿里云POLARDB如何实现?
本文讲的是6倍性能差100TB容量,阿里云POLARDB如何实现,POLARDB是阿里云数据库团队研发的基于第三代云计算架构下的商用关系型云数据库产品,实现100%向下兼容MySQL 5.6的同时,支持单库容量扩展至上百TB以及计算引擎能力及存储能力的秒级扩展能力,对比MySQL有6倍性能提升及相对于商业数据库实现大幅度降低成本。
15835 0
|
存储 消息中间件 Cloud Native
时序数据库永远的难关 — 时间线膨胀(高基数 Cardinality)问题的解决方案
本文主要讨论 influxdb 在遇到写入的数据出现高基数 Cardinality 问题时,一些可行的解决方案。
2132 112
时序数据库永远的难关 — 时间线膨胀(高基数 Cardinality)问题的解决方案
|
缓存 算法
总结两种常见的长列表分页缓存策略
通常,对于长列表加载的场景,都需要进行分页, 如最近的世界杯体育垂站项目中的赛程页,评论流,直播流。而为了提高分页加载的性能,往往需要对分页进行缓存。 下面总结对两种常见的分页缓存的策略, 适用场景以及各自的优缺点。     策略一: 直接对分页结果缓存 顾名思义,就是直接缓存每次分页查询的结果。  
8855 0
|
存储 缓存 算法
2017双11技术揭秘—分布式缓存服务Tair的热点数据散列机制
Tair是阿里巴巴集团自研的弹性缓存/存储平台,在内部有着大量的部署和使用。Tair的核心组件是一个高性能、可扩展、高可靠的NoSQL存储系统。目前支持MDB、LDB、RDB等存储引擎。本文基于Tair的存储和访问原理,对缓存的读写热点问题进行讨论,并给出一个满足现阶段需求的热点数据读写问题的解决方案。
10037 112
|
NoSQL Shell Redis
理解Docker容器的进程管理
Docker在进程管理上有一些特殊之处,本文会分析Docker进程管理的技术细节,并介绍一些常见问题的解决方法和注意事项。
44916 84
|
SQL 存储 关系型数据库
PolarDB-X 热点优化系列 (一):如何支持淘宝库存热点更新
本文主要介绍PolarDB-X中支持热点行的优化思路和基本使用。
1125 1
PolarDB-X 热点优化系列 (一):如何支持淘宝库存热点更新
|
NoSQL Redis 数据安全/隐私保护
使用redis-cli登录远程redis服务并批量导入数据
使用redis-cli登录到远程部署的redis服务
1025 0
|
缓存 NoSQL 关系型数据库
性能第三讲:百万级QPS,支撑淘宝双11需要哪些技术
性能第三讲:百万级QPS,支撑淘宝双11需要哪些技术
3052 0
|
消息中间件 存储 Kafka
谈一谈Kafka在高性能和数据一致性之间做的妥协与改进
CAP定理是分布式系统的基本定理,描述了一致性、可用性和分区容错性三大特性,只能满足两种,开发者必须在此做出取舍。而 Kafka 作为一款高性能的消息队列与分布式存储系统,必然要在高性能和数据一致性之间做出取舍,本文在这方面做了一番探索。
1011 0

热门文章

最新文章