尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

软件设计的一些感想

软件设计的一些感想 软件设计的一些感想做了十几年软件写过无数行代码也重构过无数个深夜。回头看软件设计这件事最难的从来不是技术选型或者算法优化而是如何在复杂中保持简单在变化中守住稳定。今天不聊高深的理论就说说我在实战中踩过的坑、悟出的理。### 一、设计的第一原则别过度设计很多程序员包括年轻时的我有个通病——拿到需求就想用最“优雅”的模式工厂、单例、观察者全往上堆。结果呢代码量翻倍维护成本飙升最后连自己都看不懂。教训案例我曾参与一个内部工具项目需求只是“读取配置文件并打印”。结果架构师硬是搞了一个插件化框架支持动态加载、热更新、远程配置。上线三个月没人敢改配置因为改一个字段要动五个模块。正确姿势先写最简单的代码满足当前需求即可。等第二个类似需求出现时再考虑抽象。这就是YAGNI原则You Aren’t Gonna Need It。python# 反面教材过度设计的配置读取class ConfigManager: def __init__(self, source_type, cache_enabled, retry_times): self.source self._create_source(source_type) self.cache Cache(cache_enabled) self.retry RetryPolicy(retry_times) # 50行初始化代码...# 正面教材先跑起来再说import jsondef load_config(path): 简单到不能再简单的配置读取 with open(path, r) as f: return json.load(f) # 够用真的够用### 二、命名是门艺术别用拼音和缩写代码是写给机器执行的但更是写给下一个读代码的人看的。这个人可能是三个月后的你。好的命名让代码自解释烂命名让人想骂娘。真实案例某项目里有个变量叫dta我猜是data的缩写但全项目有7个不同的dta。还有函数getXX()没人知道XX是什么。最后重构时光改名就花了三天。命名原则- 变量/函数名要能读出来比如user_name而不是un- 布尔变量用is_/has_开头如is_valid- 函数名用动词开头如calculate_total()而不是total_calc()python# 糟糕的命名def c(t, p): r t * p * 0.1 return r# 清晰的命名def calculate_commission(total_sales, commission_rate): 计算销售提成 commission total_sales * commission_rate * 0.1 return commission### 三、模块化高内聚低耦合这是老生常谈但做起来极难。我见过太多“面条代码”——一个函数500行全局变量满天飞。模块化的核心思想是**每个模块只做一件事模块之间通过清晰的接口通信**。**我的经验**写代码前先画个简单的依赖图哪怕在脑子里。如果A模块要import B模块的私有变量那说明设计有问题。正确的做法是让B暴露一个方法。python# 反例模块间互相摸对方内部class Order: def __init__(self): self.items [] self.total 0# 其他模块直接改order.items改order.total导致状态不一致# 正例封装操作class Order: def __init__(self): self._items [] self._total 0 def add_item(self, price): self._items.append(price) self._total price # 内部维护外部只调用接口 def get_total(self): return self._total### 四、注释写“为什么”不写“是什么”代码本身能说明“是什么”但永远无法说明“为什么”。我见过大量注释在解释语法比如# 循环遍历列表这毫无价值。真正有用的注释是解释背后的业务逻辑或设计权衡。好注释的范例pythondef calculate_salary(employee): # 为什么这里要乘以0.8因为公司规定绩效扣20% # 这是2023年新政策详见需求文档PRD-2023-001 base employee.base_salary * 0.8 return base烂注释的范例python# 循环for i in range(10): # 打印 print(i) # 这注释等于没说### 五、重构是常态别怕改代码很多程序员把代码当“亲儿子”不敢动。但软件设计的本质是持续演进。需求会变技术会更新唯一不变的是变化本身。我现在的习惯是每完成一个功能就回头看看能不能简化每两周做一次小型重构。重构小技巧1. 先写测试保证重构不破坏功能2. 小步快跑每次只改一个点3. 用工具辅助如IDE的重命名、提取方法功能python# 重构前一堆重复逻辑def process_order(order): if order.type online: shipping 10 tax order.amount * 0.1 elif order.type offline: shipping 0 tax order.amount * 0.05 # 其他类型...# 重构后策略模式但别过度这里用简单字典即可def get_shipping_and_tax(order_type, amount): config { online: {shipping: 10, tax_rate: 0.1}, offline: {shipping: 0, tax_rate: 0.05}, } data config[order_type] return data[shipping], amount * data[tax_rate]### 六、设计模式工具不是目标设计模式是前人总结的套路但别为了模式而模式。我在面试时经常问“你用过哪些设计模式”很多人能背出23种模式的定义但让他实际写代码却用不出一个。真正的掌握是在遇到问题时自然想到“哦这个场景适合用观察者模式”。我的建议先把基础语法练熟然后多读开源项目源码如Flask、Requests。看别人怎么组织代码比看10本设计模式书都管用。### 七、关于测试不是负担是安全网我年轻时最讨厌写测试觉得浪费时间。直到有一次改一个核心模块没测试结果上线后炸了花了两天排查。从此以后关键逻辑必写测试。测试不是证明代码没问题而是让你敢改代码——因为有测试兜底重构才不慌。python# 一个简单的单元测试示例import unittestdef add(a, b): return a bclass TestAdd(unittest.TestCase): def test_positive_numbers(self): self.assertEqual(add(2, 3), 5) def test_negative_numbers(self): self.assertEqual(add(-1, 1), 0)if __name__ __main__: unittest.main()### 八、总结软件设计没有银弹但有一些朴素的真理保持简单、重视命名、模块清晰、注释讲原因、敢于重构、测试护航。这几条听起来容易做起来需要自律和长期刻意练习。最后送大家一句话“代码是给人看的只是顺便给机器执行。”下次写代码时想想下一位读者——无论是你的同事还是三个月后的自己。设计感不是炫技而是让代码变得可读、可维护、可演进。这就是我对软件设计最深的感想。
返回列表