架构设计原则:SOLID 与 KISS
核心要点
- SOLID 原则:单一职责、开闭原则、里氏替换、接口隔离、依赖倒置
- KISS 原则:保持简单
- DRY 原则:不要重复自己
- YAGNI 原则:不要过度设计
- 架构模式:分层架构、微服务、事件驱动
- 实际案例:应用设计原则重构代码
上周帮朋友看了他写的一个项目代码,差点没把我气笑。
一个简单的用户管理系统,写成了一团乱麻。用户信息验证、数据库操作、邮件发送、日志记录,所有逻辑都堆在一个类里,几百行代码下来,连他自己都找不到某个功能在哪里。
这就是典型的架构设计原则缺失的结果。今天就聊聊两个最基础但最重要的架构设计原则:SOLID 和 KISS。
什么是 SOLID 原则?
SOLID 是五个设计原则的首字母缩写:
单一职责原则 (SRP)
一个类应该只有一个引起变化的原因。
比如用户管理系统中,用户信息验证、数据库操作、邮件发送、日志记录应该分开成不同的类。这样如果需要修改验证逻辑,只会影响验证类,不会影响其他功能。
开闭原则 (OCP)
软件实体应该对扩展开放,对修改关闭。
意思是当需要添加新功能时,应该通过扩展现有代码来实现,而不是修改现有代码。比如需要添加新的用户验证方式,可以继承现有的验证类,而不是修改原有的验证方法。
里氏替换原则 (LSP)
子类应该能够替换父类而不改变程序的正确性。
比如一个鸟类抽象类有一个“飞”的方法,那么子类麻雀、老鹰都应该实现这个方法。但如果子类是企鹅,那么就不应该实现“飞”的方法,因为企鹅不会飞。这时候需要重新设计抽象类。
接口隔离原则 (ISP)
客户端不应该被迫依赖它不需要的接口。
意思是接口应该尽可能小,只包含客户端需要的方法。比如一个打印机接口,不应该包含扫描、复印等方法,因为有些打印机只支持打印功能。
依赖倒置原则 (DIP)
高层模块不应该依赖低层模块,二者都应该依赖抽象。
抽象不应该依赖细节,细节应该依赖抽象。比如高层模块的业务逻辑不应该直接依赖低层模块的数据库操作,而是应该依赖一个抽象的数据访问接口。
什么是 KISS 原则?
KISS 原则是“Keep It Simple, Stupid”的缩写,意思是保持简单。
软件开发中,简单的方案往往比复杂的方案更有效。复杂的方案可能会带来更多的问题,比如维护困难、性能下降、调试复杂等。
比如,有些开发者喜欢使用复杂的设计模式,即使简单的方案就能解决问题。这样不仅会增加开发时间,还会让代码难以理解和维护。
其他重要原则
除了 SOLID 和 KISS 原则,还有一些其他重要的设计原则:
DRY 原则
DRY 原则是“Don’t Repeat Yourself”的缩写,意思是不要重复自己。
软件开发中,相同的代码不应该重复出现。如果发现有重复的代码,应该将其提取到一个公共的方法或类中。这样不仅可以减少代码量,还可以提高代码的可维护性。
YAGNI 原则
YAGNI 原则是“You Aren’t Gonna Need It”的缩写,意思是不要过度设计。
软件开发中,不要添加不需要的功能。有些开发者喜欢提前预测未来的需求,添加一些可能永远不会用到的功能。这样不仅会增加开发时间,还会让代码变得复杂。
实际案例:应用设计原则重构代码
让我用朋友的用户管理系统作为例子,展示如何应用设计原则重构代码。
重构前的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| class UserManager: def __init__(self): self.db = Database() self.mailer = Mailer() self.logger = Logger() def register_user(self, username, password, email): if len(username) < 3: raise Exception("用户名长度不能少于3个字符") if len(password) < 6: raise Exception("密码长度不能少于6个字符") if "@" not in email: raise Exception("邮箱格式不正确") user = {"username": username, "password": password, "email": email} self.db.save(user) self.mailer.send_welcome_email(email) self.logger.log(f"用户注册成功:{username}") def login_user(self, username, password): user = self.db.find({"username": username}) if not user: raise Exception("用户不存在") if user["password"] != password: raise Exception("密码错误") self.logger.log(f"用户登录成功:{username}") def reset_password(self, username, email): user = self.db.find({"username": username, "email": email}) if not user: raise Exception("用户不存在") new_password = self.generate_random_password() user["password"] = new_password self.db.update(user) self.mailer.send_reset_password_email(email, new_password) self.logger.log(f"密码重置成功:{username}") def generate_random_password(self): import random import string return ''.join(random.choices(string.ascii_letters + string.digits, k=8))
|
重构后的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| class UserValidator: @staticmethod def validate_username(username): if len(username) < 3: raise Exception("用户名长度不能少于3个字符") @staticmethod def validate_password(password): if len(password) < 6: raise Exception("密码长度不能少于6个字符") @staticmethod def validate_email(email): if "@" not in email: raise Exception("邮箱格式不正确") @staticmethod def validate_register_info(username, password, email): UserValidator.validate_username(username) UserValidator.validate_password(password) UserValidator.validate_email(email)
class UserRepository: def __init__(self, db): self.db = db def save_user(self, user): self.db.save(user) def find_user_by_username(self, username): return self.db.find({"username": username}) def find_user_by_username_and_email(self, username, email): return self.db.find({"username": username, "email": email}) def update_user(self, user): self.db.update(user)
class UserMailer: def __init__(self, mailer): self.mailer = mailer def send_welcome_email(self, email): self.mailer.send_welcome_email(email) def send_reset_password_email(self, email, new_password): self.mailer.send_reset_password_email(email, new_password)
class UserLogger: def __init__(self, logger): self.logger = logger def log_register_success(self, username): self.logger.log(f"用户注册成功:{username}") def log_login_success(self, username): self.logger.log(f"用户登录成功:{username}") def log_reset_password_success(self, username): self.logger.log(f"密码重置成功:{username}")
class PasswordGenerator: @staticmethod def generate_random_password(): import random import string return ''.join(random.choices(string.ascii_letters + string.digits, k=8))
class UserManager: def __init__(self, validator, repository, mailer, logger, password_generator): self.validator = validator self.repository = repository self.mailer = mailer self.logger = logger self.password_generator = password_generator def register_user(self, username, password, email): self.validator.validate_register_info(username, password, email) user = {"username": username, "password": password, "email": email} self.repository.save_user(user) self.mailer.send_welcome_email(email) self.logger.log_register_success(username) def login_user(self, username, password): user = self.repository.find_user_by_username(username) if not user: raise Exception("用户不存在") if user["password"] != password: raise Exception("密码错误") self.logger.log_login_success(username) def reset_password(self, username, email): user = self.repository.find_user_by_username_and_email(username, email) if not user: raise Exception("用户不存在") new_password = self.password_generator.generate_random_password() user["password"] = new_password self.repository.update_user(user) self.mailer.send_reset_password_email(email, new_password) self.logger.log_reset_password_success(username)
|
重构结果分析
重构后的代码更加清晰、易于维护。每个类都有明确的职责,逻辑分离,符合 SOLID 原则。同时,代码也变得更加简单,符合 KISS 原则。
架构模式
除了设计原则,架构模式也是软件开发中的重要概念。常见的架构模式包括:
分层架构
分层架构将系统分为多个层次,每个层次负责不同的功能。常见的层次包括:
- 表现层:负责与用户交互
- 业务逻辑层:负责处理业务逻辑
- 数据访问层:负责与数据库交互
- 数据存储层:负责数据存储
微服务架构
微服务架构将系统拆分为多个小型服务,每个服务负责一个特定的功能。服务之间通过 API 进行通信。
事件驱动架构
事件驱动架构通过事件来驱动系统的行为。当某个事件发生时,系统会根据事件类型执行相应的操作。
总结
架构设计原则是软件开发中的重要概念,它们可以帮助开发者设计出可维护、可扩展的系统。SOLID 和 KISS 原则是最基础但最重要的设计原则,其他原则如 DRY 和 YAGNI 原则也同样重要。
在实际开发中,我们应该根据系统的需求和特点选择合适的架构模式,并应用相应的设计原则。这样可以提高代码的质量,降低维护成本,提高开发效率。
朋友的项目经过重构后,代码变得更加清晰、易于维护。他说现在修改功能时,再也不用像之前那样在几百行代码中找来找去了。
这就是架构设计原则的力量。