|
10| 0
|
[讨论] 别急着动手写代码:先想清楚这几点,后面少改八百回 |
|
软件开发从来不是一次写完就结束的事情。需求会变,技术会升级,团队会流动。一套代码能跑多久、改起来顺不顺手、新同事接手快不快,这些往往比“第一次写出来”更重要。高质量软件设计与设计模式,谈一谈从原则到实践的几条路径,设计模式不是银弹,但理解背后的原则,能帮我们少走一些弯路。 一、什么算“高质量”的软件 很多人把“能运行”等同于“好”。其实软件质量分内外两层:外部质量是用户看到的功能正确、响应快、不崩溃;内部质量是代码可读、可维护、容易改。外部质量靠测试验证,内部质量靠设计保障。 判断内部质量有几个简单标准:新同事看代码能不能快速理解?改一个功能会不会牵连一堆地方?加新需求时是“加新代码”还是“改老代码”?如果答案不乐观,说明设计需要调整。 二、几个基础的设计原则 依赖反转:高层模块不应该依赖低层模块,两者都应该依赖抽象。比如业务逻辑层不应该直接依赖具体的数据库访问类,而是依赖一个数据访问接口。这样换数据库时,业务代码不用改。 开放-封闭:对扩展开放,对修改封闭。需求来了,尽量加新类新方法,而不是改老代码。这就要求设计时预留扩展点,比如用接口、抽象类把可变部分隔离开。 里氏替换:子类应该能替换父类,程序行为不变。如果正方形继承自矩形,而矩形的宽高可以分别修改,正方形就做不到,这种继承关系就有问题。 单一职责:一个类只做一件事。看类名就能猜出它的功能,如果描述不清或者有“和”字,很可能职责过多。拆开之后,每个模块更清晰,改其中一个不影响其他。 不要重复自己:同样的逻辑只写一次。重复不仅浪费,更是隐患——改一个地方忘了改其他地方,bug就来了。抽取公共方法、用模板方法、继承、组合,都是消除重复的手段。 三、设计模式:常见场景的解法 适配器模式:当系统需要对接一个外部接口,而接口的格式、调用方式与内部不一致时,加一层适配器做转换。比如对接第三方支付接口,每家参数不同,适配器封装差异,业务层只调用统一方法。 策略模式:一个功能有多种算法,需要动态选择。比如工资发放,正式员工、兼职员工、外包员工的计薪方式不同。策略模式把算法封装成独立的类,运行时切换,避免if-else堆砌。 工厂模式:当对象的创建过程复杂、或者需要根据配置选择不同实现时,用工厂来创建。简单工厂、工厂方法、抽象工厂,本质都是把“怎么创建”和“谁来使用”分开。 单例模式:一个类只需要一个实例,比如配置管理、线程池。实现时注意线程安全,懒加载还是饿汉,取决于场景。但单例容易隐藏耦合,用多了会让代码之间偷偷依赖,反而破坏设计。 模板方法模式:父类定义算法骨架,子类实现具体步骤。比如数据导出,流程是:查数据、转格式、写文件。父类写好流程,子类实现“怎么查”“转成什么格式”,既复用代码又留出变化点。 装饰者模式:不修改原类,动态给对象添加功能。比如数据源读写,业务增长后需要加缓存、加日志、加读写分离。装饰者一层层包上去,每个功能独立,需要哪些组合哪些。 四、重构:让代码慢慢变好 软件退化是常态。需求不断加,改的人换了一茬又一茬,代码慢慢就乱了。重构不是推翻重来,是小步快跑,每次改一点,始终让系统处于可运行状态。 常用的重构手法:抽方法解决大函数,抽类解决大对象,抽父类提高复用,用设计模式降低耦合,建立分层结构。关键是每一步都要验证,不能积累到受不了再动手。 五、小步快跑:降低风险的方式 很多项目不敢改设计,是因为担心改坏了。小步快跑的思路是:每次只做一小步,每一步都有明确的目标和验证方法,确保当前版本比上一版本更好。 比如加一个新需求,先写测试,再改代码;或者先重构让代码易于扩展,再写新功能。两种做法交替,既能推进功能,又能改善结构。这和先设计后编码并不矛盾,只是把设计分成了多次迭代。 六、防止软件退化的几个习惯 一是写清楚注释,不仅写“做了什么”,更要写“为什么这么做”。二是保持代码整洁,发现“坏味道”就顺手改一下,不要等到积重难返。三是团队统一编码规范,减少理解成本。四是定期进行代码评审,不仅找bug,也看设计是否合理。 软件设计不是一次性的艺术,而是持续演进的过程。工程师高培认为设计模式是工具箱里的工具,原则是选工具的准则,重构是保持工具箱整洁的方法。三者结合,才能让代码在变化中保持优雅。 ![]() |
沪公网安备31011502402448© 2013-2026 Comsenz Inc. Powered by Discuz! X3.4 Licensed