高并发处理全景指南:从架构到运维,搞定系统扛压核心

高并发处理技术


高并发处理全景指南:从架构到运维,搞定系统扛压核心

面对秒杀活动的瞬时流量、热门 APP 的千万级用户访问,高并发系统的核心诉求只有一个:“稳得住、响应快、不宕机”。高并发处理不是单一技术的比拼,而是从架构设计、存储优化、流量管控到运维保障的全链路协同。今天就拆解高并发处理的核心技术栈,帮你搭建一套 “可扩展、可容错、高性能” 的系统架构。

一、架构设计:从 “单体” 到 “分布式”,破解性能瓶颈
高并发的核心是 “分散压力”,通过分布式架构将流量和负载分摊到多个节点,避免单点故障:
横向扩容与容器化:采用 “横向扩展” 而非 “纵向扩容”,通过增加服务器节点分摊压力;用 Docker 封装应用,K8s 实现容器编排与管理,支持弹性扩缩容(流量高峰自动加节点,低谷缩容节省资源);
微服务与服务治理:拆分单体应用为微服务(如订单、支付、用户服务),每个服务独立部署、按需扩容;通过服务网格、注册中心(ZK、ETCD、Nacos)实现服务发现与路由,搭配限流、降级、熔断机制(避免某个服务故障牵连整体);
无状态设计:服务设计为无状态(不存储本地数据,依赖分布式存储),方便水平扩容;通过 TraceID、SpanID 实现分布式链路追踪,快速定位跨服务问题;
多活与灾备:搭建多数据中心、跨中心数据同步,实现同城 / 异地多活(避免单点数据中心故障);制定全量 / 增量备份策略,确保数据安全与快速恢复。

二、流量管控:削峰填谷,让系统 “从容应对” 高峰
直接暴露核心服务给峰值流量,极易导致系统崩溃,流量管控的核心是 “缓冲、分流、限流”:
负载均衡:通过 Nginx、LVS、F5 等软 / 硬件负载均衡器,将流量均匀分发到后端服务节点;采用一致性 Hash 算法,确保请求分发均匀,减少缓存失效;
消峰填谷:用 MQ 消息队列缓冲瞬时高峰流量(如秒杀订单先入队,服务异步消费),将 “突发流量” 转化为 “平稳流量”,避免服务被压垮;
限流与灰度发布:对核心接口设置限流阈值(如每秒最多处理 1000 请求),超出阈值直接返回友好提示;通过预发布、灰度发布(逐步放量),验证新功能在高并发下的稳定性,降低风险;
DNS 与 CDN 优化:利用 DNS 轮询实现地域级流量分流(将用户导向就近节点);CDN 加速静态资源(图片、视频、JS/CSS),减少源站压力,同时提升用户访问速度。

三、存储优化:适配高并发读写,兼顾速度与可靠性
存储是高并发系统的 “数据底座”,核心需求是 “读写快、容量足、不丢数据”:
分层存储策略:静态资源(图片、视频、大文件)存入分布式存储(HDFS、Ceph 对象存储、块存储),通过 CDN 加速访问;热点数据存入 Redis 等缓存,减少数据库查询压力;
数据库优化:采用分布式数据库、主从架构(主库写、从库读,读写分离);针对高并发场景选用列数据库(适配海量数据查询)、文档数据库(MongoDB,适配非结构化数据);
缓存设计:多级缓存(浏览器缓存→CDN 缓存→服务器端缓存)减少重复请求;合理设置缓存失效时间、失效通知,搭配 LRU 等缓存淘汰算法,避免缓存雪崩、缓存穿透;
资源预分配:提前预热热点数据(如秒杀商品信息载入缓存)、预压制视频 / 图片分辨率,减少高并发时的动态处理压力。

四、核心优化:从代码到硬件,榨干系统性能
在架构和流量管控之外,细节优化能进一步提升系统并发能力,核心是 “减少无效消耗、提升单位时间处理效率”:
硬件与系统优化:选用高性能 CPU、GPU、SSD(提升读写速度);优化操作系统、JVM、网络参数(如调整连接数、内存分配);核心绑定(将进程与 CPU 核心绑定,减少上下文切换);
代码与编程模式优化:简化接口路径、减少参数传递、降低服务依赖(路径短、参数少、依赖少 = 更快响应);采用高效编程模式,避免冗余逻辑和资源浪费;
大数据与算法优化:用 MapReduce、流计算处理海量日志与业务数据,支撑实时决策;核心业务算法优化(如推荐算法采用基于人 / 物品 / 话题的高效匹配逻辑);
多媒体处理优化:对图片、声音、视频进行编解码优化,抽帧处理减少传输与存储压力。

五、运维与监控:实时预警,快速响应问题
高并发系统的稳定性离不开完善的运维监控,核心是 “早发现、早定位、早解决”:
全链路监控:监控性能指标(响应时间、QPS、错误率)、系统资源(CPU、内存、磁盘 IO);建立日志管理平台,集中分析分布式日志,快速定位问题;
自动化运维与预警:通过自动化测试、压力测试,提前验证系统抗并发能力;设置预警阈值(如响应时间超过 500ms 告警),结合服务健康检查,实时发现异常;
容错与补偿:实现重试机制(失败请求自动重试,避免偶发故障影响)、事务补偿(如支付失败自动回滚订单),提升系统容错性;
安全保障:兼顾系统安全与数据安全,防范高并发场景下的恶意攻击(如 DDoS、接口刷取),确保核心业务不被干扰。

总结:高并发处理的核心逻辑 ——“全链路协同,无短板优化”
高并发不是 “某一个技术点的胜利”,而是架构、流量、存储、代码、运维的全方位配合:架构层面 “分散压力”,流量层面 “缓冲分流”,存储层面 “提速减负”,细节层面 “榨干性能”,运维层面 “兜底保障”。
关键原则是 “避免单点故障、减少无效消耗、适配业务场景”—— 比如秒杀场景侧重 “消峰填谷 + 缓存预热”,社交 APP 侧重 “分布式存储 + 实时计算”。只有结合自身业务特点,针对性优化,才能打造出稳定、高效的高并发系统。

你在做高并发系统时,遇到过哪些棘手问题?是缓存雪崩、流量突增还是数据库瓶颈?欢迎在评论区分享你的解决方案~

【温故知新】IT行业经典定律

IT行业经典定律

一、问题认知

XY 问题:不问真正的问题 X,反而问自拟的解决方案 Y,导致更优路径被忽略。
例子:业务老师希望批量得到客户纸质表单上的几个信息(X),跑去问开发团队如何批量识别纸质表单上的数据并导出CSV文件(Y),其实这几个信息数据库都有记录。

二八法则(帕累托法则):80% 的结果由 20% 的原因产生。
例子:一个项目中20%的代码,撑起最长用的80%功能。

吉尔布定律(Gilb’s Law):任何能够被测量的东西,都能够被改进。
例子:你开始记录每天写代码的专注时长,仅仅因为”在记录”,你就会不自觉地更加专注,效率真的提升了。

幂律分布(Power Law):少数节点拥有绝大多数连接,其余节点连接极少。
例子:互联网流量里,头部 1% 的网站吃掉了 90% 的访问量;长尾那 99% 的网站加起来才分 10%。

自行车棚效应:人们对简单琐碎的问题反而投入过多讨论时间,对复杂核心问题却轻易放过。
例子:技术评审会上,复杂的分布式架构方案半小时就通过了,却为按钮颜色、接口命名风格争论了一个小时。

沃克定律(Wadler’s Law):在编程语言设计中,讨论语法所花的时间与其重要性成反比——越是无关紧要的语法细节,争论越久。
例子:语言设计委员会开了三个月会,其中两个月在吵缩进到底用 Tab 还是空格,真正的核心类型系统只聊了一下午。

汉隆剃刀定律:能解释为疏忽的问题,就不要归因为恶意。
例子:线上出现接口调用异常,优先排查参数传错、文档遗漏等疏忽问题,不要先假定是对方团队故意为之。

坎宁汉定律(Cunningham’s Law):在互联网上想得到正确答案的最好方法,不是提问,而是发布一个错误的答案。
例子:你在技术论坛发帖”Python 肯定没有 GIL 吧?”——十分钟内就会有八个老哥跳出来把你纠正一遍,顺便把原理讲透。

二、风险管理

墨菲定律:凡是可能出错的事情,就一定会出错。(而且经常在最不能承受的时候发生)
例子:某直播平台,发现直播推流接口只判断了Token没再次去鉴权,为了兼容旧接口一再推迟上线时间。最后被黑客组织利用,导致近年来最大的直播事故。

演示定律:每当你当众演示系统时,它大概率会出故障。
例子:本地和测试环境跑了几十次都正常的功能,给客户现场演示时刚好触发边界条件直接闪退。

海因里希法则:每 1 起严重事故背后,对应 29 起轻微事故与 300 起未遂隐患。
例子:出现 1 次线上 P0 级数据故障,往前排查能发现 29 次线上小异常告警,以及 300 次被忽略的代码不规范和测试用例缺失。但实际情况是大家经常把这些小问题忽视了。

三、项目管理

霍夫施塔特定律:做事耗时总比预期长,即便你已经考虑了这条定律本身。
例子:你预估需求开发要 2 周,特意多预留了 3 天缓冲时间,最终还是因为需求变更、联调卡点超期了。

计划谬误定律:人们总会低估任务耗时,即便有过往经验也难以避免。
例子:你评估一个简单表单开发只需要 3 天,实际对接接口、处理兼容、改需求加校验,最后花了整整一周才上线。

帕金森定律:工作会自动膨胀,直至填满所有可用时间。
例子:原本 2 周就能做完的需求,给了 1 个月的排期,最后真的会拖到截止日前两三天才集中完成。

功能膨胀定律:系统一旦开放扩展,功能会持续增生直至臃肿,必须主动设界。
例子:在IE时代,所有人都觉得IE很慢。于是微软内部有团队用开源引擎重新开发了一个新版浏览器,一开始效果很好,但随着对IE各种功能兼容的越来越多,这个浏览器变得比IE还慢而且经常崩溃,最后这个项目被砍了。后来做Edge的时候,很多IE的功能是不兼容的,扔掉了旧包袱,让Edge比IE好用的多。

90-90 法则:软件开发前 90% 的功能耗费 90% 的工期,剩下 10% 的收尾工作也会耗费 90% 的工期。
例子:核心业务逻辑很快开发完成,以为即将上线,结果边界场景兼容、异常处理、性能优化等收尾工作,又花掉了和主开发几乎等量的时间。

克尼汉定律(Kernighan’s Law):调试一段一开始就写错的代码,比重新写一遍要难一倍。
例子:你从别人手里接了一段绕来绕去的代码,修了 A 处冒出 B 处 Bug;折腾三天后索性推倒重写,半天搞定。

布鲁克斯定律:向已延期的软件项目加人,只会让它完成得更晚。
例子:项目已经延期两周,临时新增 3 名开发加入,老员工需要花大量时间做业务讲解、代码交接和环境搭建,整体进度反而进一步延后。

沉默成本谬误(Sunk Cost Fallacy):人们倾向于继续投入资源到一个已经失败的项目中,仅仅因为已经投入了很多。
例子:花了两年做的产品根本没市场,团队却说”都做了两年了,放弃太可惜”,又烧了一年钱才彻底关停。

四、系统设计

康威定律:系统的架构必然复刻设计它的组织的沟通结构。
例子:公司业务团队拆分成三条线,各自定业务规则,各自提系统需求。最终做出来的系统就会是底层三套相互割裂的规则,表面上被捆绑在一起。

阿姆达尔定律:并行系统的加速上限,由程序中无法并行的串行部分占比决定。
例子:一个任务 90% 逻辑可多线程并行,10% 必须串行执行,就算开到 100 个线程,整体速度最多也只能提升 10 倍。
例子:一个组织编码工作只占10%,其余90%工作需要串行,哪怕编码工作提升到耗时为0,整体效率也只能提升11%。

泰斯勒定律(复杂性守恒原理):复杂性不会凭空消失,只会从一处转移到另一处。
例子:把单体系统拆成微服务后,单个服务的业务逻辑变简单了,但服务治理、链路追踪、分布式事务的整体复杂度反而大幅增加。
例子:各类跨平台的框架,开发用的很爽,无需各种适配,一次写完可以编译为各平台的Native程序。因为复杂度被底层框架承接了。
例子:为了赶工期,做了很多硬编码,项目匆匆上线。最后要花更多的时间,重构这些代码。

盖尔定律(Gall’s Law):一个切实可行的复杂系统,总是从一个切实可行的简单系统演化而来的。
例子:想一步到位做个”完美架构”的微服务系统,往往直接失败;从单体应用起步、随着业务增长逐步拆分,反而能活下来。

伊格尔森定律:自己六个月前写的代码,和别人写的没什么两样,同样看不懂。
例子:回头修改半年前写的工具类代码,因为没写注释、命名随意,自己都要花半天才能理清逻辑,完全看不出是自己写的。

海勒姆定律:API 用户足够多时,其所有可观测行为(含未文档细节)都会被人依赖。
例子:接口文档没声明返回列表的排序规则,但大量下游业务默认按当前顺序处理,后续优化排序逻辑后直接引发大面积业务异常。

死代码悖论:你因为 “以后可能用得到” 而保留的代码,永远不会被真正用到,只会持续增加维护负担。
例子:开发时顺手保留了三套备用实现逻辑没删掉,后续迭代中这些代码既没人用,还经常在重构时引发编译错误和理解成本。

CAP 定理:分布式系统最多只能同时满足一致性、可用性、分区容错性中的两项。
例子:电商下单系统优先保证数据一致性和分区容错,网络分区发生时就会暂停下单操作,牺牲部分可用性。

五、质量管理

沃斯定律:软件变慢的速度,永远快过硬件性能提升的速度。
例子:电脑 CPU 性能相比五年前翻了数倍,但新版 IDE、编辑器的内存占用和启动耗时也同步膨胀,日常使用体感并没有明显提速。

缺陷聚集原则:软件缺陷并非均匀分布,绝大多数集中在少数模块中。
例子:项目中频繁迭代、改动最多的用户认证模块,集中了全系统近 70% 的线上缺陷。

林纳斯定律:足够多的眼睛审视,就能让所有问题浮出水面。
例子:开源项目面向全球开发者开放源码审查,隐藏的深层漏洞往往比闭源项目更快被发现和修复。

破窗效应:不良现象一旦被放任,就会诱使人们效仿甚至变本加厉。
例子:代码里一处没人清理的冗余逻辑和临时写法,很快会让整个模块都充满不规范的代码。

格雷沙姆定律:劣币驱逐良币 —— 当劣质币和优质币同时流通时,人们会囤积优质币、花出劣质币,最终市场上只剩下劣质币。。
例子:项目赶工期时大量临时拼凑的烂代码被合入主干,并被业务方称赞响应及时。好好写代码,重构提升代码质量的开发,被嫌弃响应缓慢。久而久之整洁规范的代码越来越少,代码库整体质量持续下滑。

六、组织管理

古德哈特定律:当一项指标被当作考核目标,它就不再是一个好的衡量指标。
例子:团队把代码行数作为开发工作量考核标准,最终大家疯狂堆砌冗余代码,整体代码质量不升反降。

德西效应(Deci Effect):过度使用外部奖励反而会削弱内在动机。
例子:孩子本来爱画画,你每次画完给 10 块钱,三个月后不给钱他就不画了——原本的兴趣被”买”没了。

彼得定律(Peter Principle):在一个等级制度中,每个员工都会晋升到他不能胜任的职位。
例子:顶尖的销售员被提拔成销售总监,结果他不懂管理,团队业绩一路下滑。

呆伯特定律(Dilbert Principle):公司往往会把最无能的员工提升到管理层,让他们离开一线,从而减少对实际工作的破坏。
例子:那个搞砸了三个项目的老员工,被”升”为中层管理者,从此只开会不干活,反而对公司危害小了。

【温故知新】设计原则

设计原则


设计原则

一、SOLID 原则

单一职责原则

  • Single Responsibility Principle,SRP
    一个类/模块仅负责一项明确职责,避免功能混杂。
  • Separation of Concerns,SoC
    注点分离原则,把一个复杂的系统分成多个部分,每个部分只关注一件事。

开闭原则

  • Open Closed Principle,OCP
    对扩展开放(可新增功能),对修改关闭(不改动现有代码)。

里式替换原则

  • Liskov Substitution Principle,LSP
    子类必须能完全替代父类,且不破坏原有业务逻辑。

接口隔离原则

  • Interface Segregation Principle,ISP
    客户端不应依赖它不需要的接口,拆分臃肿接口为专用小接口。

依赖反转原则

  • Dependency Inversion Principle,DIP
    高层模块不依赖低层模块,二者均依赖抽象;抽象不依赖细节,细节依赖抽象。
  • 依赖注入Dependency Injection
    通过外部传入依赖对象(而非内部创建),解耦组件与依赖。
  • 控制反转Inversion Of Control
    将对象创建、流程控制的主动权交给框架,而非硬编码在业务代码中。

二、KISS原则

Keep It Simple and Straightforward

设计力求简单直接,复杂逻辑会增加维护成本与出错风险。

奥卡姆剃刀原理(Occam’s Razor)

当多个方案都能达成同一目标时,选择假设最少、最简单的那一个——”如无必要,勿增实体”(Entities should not be multiplied unnecessarily)。

三、YAGNI原则

You Ain’t Gonna Need It

不提前开发当前不需要的功能,避免过度工程。

过早优化是万恶之源

premature optimization is the root of all evil.

Rule of Three

同一段代码第三次出现时才重构复用,避免过度设计。

四、迪米特法则

Law of Demeter,LOD

对象仅与直接关联的对象交互,不依赖间接依赖的内部细节。——“只和直接朋友说话,不和陌生人说话”。

高内聚、低耦合

模块内部逻辑紧密相关(高内聚),模块间依赖尽可能少(低耦合)。

最小知识原则,The Least Knowledge Principle

对象应最小化对其他对象的了解,仅知晓必要的接口信息。

组合优先于继承原则,Composition Over Inheritance

设计中尽量使用组合而不是通过类继承来复用功能

五、最低入侵原则

Spring对比EJB

Spring无需实现特定接口或继承框架类(低入侵),EJB则强依赖框架规范(高入侵)。

六、DRY 原则

Don’t Repeat Yourself

避免重复代码与逻辑,通过抽象统一维护相同知识。

复用代码,Code Reusability

通过封装通用逻辑(函数/类/模块),减少重复编写。

不要重复造轮子

如果没有不得不做的理由,千万不要重复造轮子。

七、面向对象

封装、抽象、继承、多态

隐藏内部实现细节,仅通过公开接口与外界交互。

八、高级抽象

Linux中一切皆文件

将设备、进程等系统资源统一抽象为文件,用同一套API访问。

九、分层及模块化

按职责拆分系统为独立层/模块,降低耦合,提升可维护性。

十、为扩展而设计

预留扩展接口,确保新增功能时无需大幅修改现有代码。

十一、波斯特定律(鲁棒性原则):发送时保守,接收时宽容。

对外提供接口时,自身输出的参数严格遵循格式规范;对接上游数据时,对合理的格式差异做兼容处理,提升系统整体容错性。

十二、最小惊奇原则

The Least Surprise Principle

代码行为应符合开发者直觉,避免反常识的设计。

十三、为维护者写代码

为维护者写代码、注释和文档

十四、拥抱变化

欢迎需求变更,即使在开发后期。敏捷过程利用变更为客户带来竞争优势。——《敏捷宣言》

十五、不要让用户思考

Don’t make me think!

十六、不要给客户行为做过多假设

你永远不知道用户怎么使用你的软件

十七、及时处理代码的坏味道(破窗效应)

当代码质量下滑的时候,及时修复问题,否则只会获得一堆低质量代码

【温故知新】设计模式

设计模式

一、23种设计模式

设计模式

分类 模式名称 一句话定义 核心要点 典型应用场景
创建型(5种) 单例Singleton 保证一个类只有一个实例 私有构造、全局访问点 日志管理器、数据库连接池、配置对象
工厂方法Factory Method 定义创建对象的接口,由子类决定实例化谁 类级别、依赖继承 日志记录器(文件/数据库)、支付渠道选择
抽象工厂Abstract Factory 创建一组相关或相互依赖的对象族 对象组合、拒绝多if-else 跨平台UI组件(Win/Mac按钮和文本框)
建造者Builder 分步构建复杂对象,分离构造与表示 链式调用、Director指挥 SQL查询构造器、StringBuilder、复杂订单
原型Prototype 通过拷贝现有对象来创建新对象 实现Clone接口、浅/深拷贝 游戏怪物克隆、对象初始化成本高的场景
结构型(7种) 适配器Adapter 将一个类的接口转换成客户端期望的接口 包装器、兼容旧代码 电源转接头、第三方SDK接口适配
桥接Bridge 将抽象与实现分离,让它们独立变化 组合优于继承 消息发送(抽象:普通/紧急 vs 实现:邮件/SMS)
装饰器Decorator 动态地给对象添加职责,比继承灵活 层层包裹、透明扩展 Java I/O流 (BufferedInputStream)
代理Proxy 为对象提供一个代理以控制访问 中介、延迟加载 虚拟代理(图片懒加载)、权限代理
外观Facade 为复杂的子系统提供一个统一的简单接口 简化调用、降低耦合 JDBC封装、启动电脑(一键开机)
享元Flyweight 共享细粒度对象,减少内存消耗 池化技术、内部/外部状态 字符串常量池、围棋棋子(颜色共享)
组合Composite 将对象组合成树形结构以表示”部分-整体” 递归结构、一致对待 文件系统(文件夹与文件)、组织架构树
行为型(11种) 策略Strategy 定义一系列算法,封装起来,让它们可互换 消除大量条件判断 电商促销策略(满减/折扣/返现)、排序算法
观察者Observer 定义一对多的依赖,当一个对象改变时通知所有依赖者 发布-订阅机制 事件监听(Button点击事件)、RxJava
命令Command 将请求封装成一个对象,支持撤销和排队 解耦请求者与执行者 菜单按钮操作、宏命令、线程池任务
模板方法Template Method 定义算法骨架,将某些步骤延迟到子类 钩子方法、代码复用 数据库访问流程(连接-执行-关闭)、JUnit
状态State 允许对象在其内部状态改变时改变它的行为 用多态代替if-else 订单状态流转(待支付/已发货/已完成)、电梯状态
责任链Chain of Resp. 将请求沿着处理链传递,直到被处理 解耦发送者和接收者 审批流、Servlet Filter、拦截器
备忘录Memento 在不破坏封装的前提下,捕获并恢复对象状态 快照机制 编辑器撤销(Ctrl+Z)、游戏存档
中介者Mediator 用一个中介对象封装一组对象的交互 减少对象间耦合 聊天室(通过服务器转发)、MVC的Controller
访问者Visitor 将作用于某对象结构的操作分离出来封装 数据结构稳定,操作易变 编译器(AST节点遍历)、报表生成器
迭代器Iterator 提供一种方法顺序访问聚合对象中的元素 统一遍历接口 Java Collection的 iterator()for-each
解释器Interpreter 给定一个语言,定义其文法的一种表示,并解释执行 语法树解析 正则表达式引擎、SQL解析、数学表达式计算

二、MVX设计模式

MVX设计模式

模式 全称与核心组成 数据流与交互逻辑 优点 缺点 典型应用场景
MVC Model-View-ControllerM: 数据/业务• V: 界面展示• C: 接收输入,调度M/V 双向混乱View常直接读Model,Controller同时操控View和Model。很多实现中V和C紧耦合(如iOS)。 • 概念简单,易上手• 开发速度快(小项目) Controller臃肿(Massive VC)• View与Model耦合,难测试• 逻辑分散,维护困难 • 早期Web开发(PHP/JSP)• iOS原生开发(Apple MVC)• 简单Demo或小型工具
MVP Model-View-PresenterM: 数据/业务• V: 被动视图P: 纯逻辑调度 单向清晰View <-> Presenter <-> Model。View只负责画UI,通过接口通知Presenter;Presenter持有View接口,更新UI。 彻底解耦(V与M互不知晓)• Presenter无Android/iOS Context,极易单元测试• 逻辑集中,易于维护 • Presenter易臃肿• 手动更新UI繁琐(需写大量setText等代码)• View接口可能过多 • 传统Android开发• WinForms/ASP.NET Web Forms• 需要高测试覆盖率的项目
MVVM Model-View-ViewModelM: 数据/业务• V: 界面展示• VM: View的抽象模型 双向绑定View <-> (Binder) <-> ViewModel。View与ViewModel通过框架自动同步(Data Binding),无需手动调用。 开发效率极高(消灭样板代码)• 数据驱动,代码简洁• 比MVP更解耦,测试性良好 调试困难(数据流向不直观,难定位Bug)• 内存泄漏风险(绑定未释放)• 复杂逻辑导致ViewModel膨胀 前端主流(Vue/React/Angular)• WPF/UWP• Android Jetpack (LiveData/DataBinding)• 数据密集型应用
MVPVM MVP + MVVMM: 数据• V: 视图• P: 业务逻辑VM: 数据包装 双轨制View <-> Presenter <-> ViewModel <-> Model。P负责逻辑,VM负责适配数据供V绑定。 • 兼具MVP的强测试性和MVVM的高效率• 职责分离更彻底(P只管逻辑,VM只管数据) 架构复杂,学习成本高• 类数量翻倍,代码量较大• 小型项目杀鸡用牛刀 • 大型桌面应用(WPF)• 复杂企业级移动应用• 需要严格分层的大型项目
VIPER View-Interactor-Presenter-Entity-RouterV: UI展示• I: 业务逻辑/用例• P: 格式化数据• E: 实体• R: 路由/导航 单向闭环View -> Presenter -> Interactor -> Entity。严格遵循Clean Architecture,每一层只做一件事。 职责切分到极致• 极高的可测试性和模块化• 代码极其规范,适合团队协作 类爆炸(一个页面5+文件)• 极度繁琐,开发效率低• 学习曲线非常陡峭 • 超大型iOS/Android项目• 金融、银行类App(业务极其复杂)• 长期维护的核心产品

好API的6个特质


好API的6个特质

API之于程序员就如同图形界面之于普通用户(end-user)。API中的『P』实际上指的是『程序员』(Programmer),而不是『程序』(Program),强调的是API是给程序员使用的这一事实。

在第13期Qt季刊,Matthias 的关于API设计的文章中提出了观点:API应该极简(minimal)且完备(complete)、语义清晰简单(have clear and simple semantics)、符合直觉(be intuitive)、易于记忆(be easy to memorize)和引导API使用者写出可读代码(lead to readable code)。

1 极简
极简的API是指每个class的public成员尽可能少,public的class也尽可能少。这样的API更易理解、记忆、调试和变更。

2 完备
完备的API是指期望有的功能都包含了。这点会和保持API极简有些冲突。如果一个成员函数放在错误的类中,那么这个函数的潜在用户就会找不到,这也是违反完备性的。

3 语义清晰简单
就像其他的设计一样,我们应该遵守最少意外原则(the principle of least surprise)。好的API应该可以让常见的事完成的更简单,并有可以完成不常见的事的可能性,但是却不会关注于那些不常见的事。解决的是具体问题;当没有需求时不要过度通用化解决方案。

4 符合直觉
就像计算机里的其他事物一样,API应该符合直觉。对于什么是符合直觉的什么不符合,不同经验和背景的人会有不同的看法。API符合直觉的测试方法:经验不很丰富的用户不用阅读API文档就能搞懂API,而且程序员不用了解API就能看明白使用API的代码。

5 易于记忆
为使API易于记忆,API的命名约定应该具有一致性和精确性。使用易于识别的模式和概念,并且避免用缩写。

6 引导API使用者写出可读代码
代码只写一次,却要多次的阅读(还有调试和修改)。写出可读性好的代码有时候要花费更多的时间,但对于产品的整个生命周期来说是节省了时间的。

最后,要记住的是,不同的用户会使用API的不同部分。尽管简单使用单个Qt类的实例应该符合直觉,但如果是要继承一个类,让用户事先看好文档是个合理的要求。

转载自coolshell

设计模式笔记

设计模式
1、设计模式原则
开放封闭原则:一个类,对修改封闭,对扩展开放
依赖反转原则:依赖于抽象而不是具体实现,实现依赖接口,接口不依赖于实现
迪米特法则:尽量减少与其他类的关系,降低类之间耦合度
里氏转换原则:子类必须能替代父类
接口隔离原则:类的依赖建立在最小接口之上,多个小接口优于一个大接口
合成复用原则:聚合优先于继承

2、简单工厂
将创建实例的代码,集中到一个类中,实现一个类创建多种实例。

3、工厂模式
将创建实例的代码,在工厂子类中实现,调用者负责使用哪个工厂。

4、抽象工厂
将工厂抽象为一系列的接口,在每个工厂子类中,用工厂方法实现这些接口。

5、模板方法
创建对象的步骤固定,每个步骤都放到子类中实现。

6、生成器
创建对象的步骤不固定,但组件固定,可以方便的增加各种组件。

7、策略模式
多种算法,在使用时,指定选用的算法。

8、状态模式
多种算法,根据对象的状态,选用对应的算法。

9、装饰者
包装现有对象,增加功能。

10、外观
将一系列复杂接口,重新组成一个简单的接口。

11、迭代器
不暴露细节的前提下,提供遍历
Java、DotNet
12、组合
对象和组,采用相同的方式来实现
菜单
13、代理
提供代理类,间接访问对象,提供访问控制,调用者不知道被代理类的存在
远程代理,虚拟代理
14、桥接
采用桥接类,利用组合访问的方式,处理桥接对象之间的访问

15、适配器
封装原有接口,成为新接口

16、观察者
对象状态改变,通知其他对象

17、访问者
不改变原来实现的前提下,通过访问者,提供新功能(破坏封装)

18、中介者
多个对象之间的访问,改变为对象与中介者之间的访问

19、命令
将请求封装为对象,可以回滚

20、备忘录
记录状态,随时回滚

21、单件
最多只有一个实例

22、蝇量(享元)
同一类的大量实例,共享存储

23、原型
复制复杂对象,而并非重新创建对象

24、解释器
嵌入式语言

25、责任链
消息响应链

26、组合模式
MVC等

好书推荐:
《Head First设计模式》、《大话设计模式》、《23种设计模式》