# Clean Code Principles # 整洁代码原则 ## Core Principles ## 核心原则 ### 1. Meaningful Names ### 1. 有意义的命名 **Variables**: **变量**: ```python # BAD d = 10 # What is 'd'? t = time.time() # GOOD elapsed_days = 10 current_timestamp = time.time() ``` **Functions**: **函数**: ```python # BAD def process(data): pass # GOOD def calculate_user_average_score(user_scores): pass ``` **Classes**: **类**: ```python # BAD class Data: pass # GOOD class CustomerOrderProcessor: pass ``` **Boolean variables** - use predicates: **布尔变量**——使用谓词: ```python # BAD flag = True status = False # GOOD is_active = True has_permission = False can_edit = True should_retry = False ``` --- ### 2. Functions Should Do One Thing ### 2. 函数应该只做一件事 **BAD** - Multiple responsibilities: **反面示例**——多重职责: ```python def process_user_data(user): # Validate if not user.email: raise ValueError("Email required") # Transform user.name = user.name.upper() # Save to database db.save(user) # Send email email_service.send_welcome(user.email) # Log logger.info(f"User processed: {user.id}") ``` **GOOD** - Single responsibility: **正面示例**——单一职责: ```python def validate_user(user): if not user.email: raise ValueError("Email required") def normalize_user_data(user): user.name = user.name.upper() return user def save_user(user): db.save(user) def send_welcome_email(email): email_service.send_welcome(email) def process_user_data(user): validate_user(user) user = normalize_user_data(user) save_user(user) send_welcome_email(user.email) logger.info(f"User processed: {user.id}") ``` --- ### 3. Keep Functions Small ### 3. 保持函数短小 **Guideline**: Aim for 10-20 lines per function. **指导原则**:每个函数控制在 10–20 行。 **BAD** - 100+ line function: **反面示例**——超过 100 行的函数: ```python def generate_report(users): # 100 lines of mixed logic # Filtering, sorting, formatting, calculations, file I/O pass ``` **GOOD** - Extracted functions: **正面示例**——提取后的函数: ```python def generate_report(users): active_users = filter_active_users(users) sorted_users = sort_by_activity(active_users) report_data = calculate_statistics(sorted_users) formatted_report = format_report(report_data) save_report(formatted_report) def filter_active_users(users): return [u for u in users if u.is_active] def sort_by_activity(users): return sorted(users, key=lambda u: u.activity_score, reverse=True) ``` --- ### 4. DRY (Don't Repeat Yourself) ### 4. DRY(不要重复自己) **BAD** - Duplication: **反面示例**——重复代码: ```python def calculate_student_grade(math_score, science_score): if math_score >= 90: math_grade = 'A' elif math_score >= 80: math_grade = 'B' elif math_score >= 70: math_grade = 'C' else: math_grade = 'F' if science_score >= 90: science_grade = 'A' elif science_score >= 80: science_grade = 'B' elif science_score >= 70: science_grade = 'C' else: science_grade = 'F' return math_grade, science_grade ``` **GOOD** - Extract common logic: **正面示例**——提取公共逻辑: ```python def score_to_grade(score): if score >= 90: return 'A' elif score >= 80: return 'B' elif score >= 70: return 'C' return 'F' def calculate_student_grade(math_score, science_score): return score_to_grade(math_score), score_to_grade(science_score) ``` --- ### 5. Avoid Magic Numbers ### 5. 避免魔数 **BAD**: **反面示例**: ```python if age > 18: can_vote = True if len(password) < 8: raise ValueError("Password too short") ``` **GOOD**: **正面示例**: ```python VOTING_AGE = 18 MIN_PASSWORD_LENGTH = 8 if age > VOTING_AGE: can_vote = True if len(password) < MIN_PASSWORD_LENGTH: raise ValueError(f"Password must be at least {MIN_PASSWORD_LENGTH} characters") ``` --- ### 6. Error Handling ### 6. 错误处理 **BAD** - Bare except, silent failures: **反面示例**——裸 except、静默失败: ```python try: result = risky_operation() except: pass # What went wrong? ``` **GOOD** - Specific exceptions, informative messages: **正面示例**——具体异常、信息性消息: ```python try: result = risky_operation() except ValueError as e: logger.error(f"Invalid value: {e}") raise except ConnectionError as e: logger.error(f"Connection failed: {e}") # Retry or fallback logic ``` --- ### 7. Use Early Returns (Guard Clauses) ### 7. 使用提前返回(卫语句) **BAD** - Nested conditions: **反面示例**——嵌套条件: ```python def process_order(order): if order is not None: if order.is_valid(): if order.total > 0: if order.customer.has_credit(): # Process order return True return False ``` **GOOD** - Early returns: **正面示例**——提前返回: ```python def process_order(order): if order is None: return False if not order.is_valid(): return False if order.total <= 0: return False if not order.customer.has_credit(): return False # Process order return True ``` --- ### 8. Comment Why, Not What ### 8. 注释说明「为什么」,而非「是什么」 **BAD** - Obvious comments: **反面示例**——显而易见的注释: ```python # Increment i by 1 i += 1 # Loop through users for user in users: pass ``` **GOOD** - Explain non-obvious reasoning: **正面示例**——解释非显而易见的理由: ```python # Use binary search because list is always sorted # and can contain millions of items index = binary_search(sorted_list, target) # Cache for 5 minutes to reduce database load # during peak hours (based on profiling data) @cache(ttl=300) def get_popular_products(): pass ``` --- ### 9. Keep Indentation Shallow ### 9. 保持缩进深度较浅 **BAD** - Deep nesting: **反面示例**——深层嵌套: ```python def process_data(items): for item in items: if item.is_valid(): if item.quantity > 0: if item.price > 0: if item.in_stock: # Process pass ``` **GOOD** - Use early returns, extraction: **正面示例**——使用提前返回和提取: ```python def process_data(items): for item in items: if not should_process_item(item): continue process_item(item) def should_process_item(item): return (item.is_valid() and item.quantity > 0 and item.price > 0 and item.in_stock) ``` --- ### 10. Consistent Formatting ### 10. 一致的格式化 **Use a formatter**: Black (Python), Prettier (JavaScript), gofmt (Go) **使用格式化工具**:Black (Python)、Prettier (JavaScript)、gofmt (Go) **Consistency matters**: **一致性很重要**: ```python # Pick one style and stick to it # 选择一种风格并坚持使用 # Style 1 def foo(x, y, z): return x + y + z # Style 2 def foo( x, y, z ): return x + y + z # Don't mix them randomly in the same file! # 不要在同一个文件中随意混用! ``` --- ## SOLID Principles ## SOLID 原则 ### S - Single Responsibility Principle ### S——单一职责原则 **A class should have one, and only one, reason to change.** **一个类应该只有一个、且仅有一个变更理由。** **BAD**: **反面示例**: ```python class User: def __init__(self, name, email): self.name = name self.email = email def save(self): # Database logic db.execute(f"INSERT INTO users...") def send_email(self, message): # Email logic smtp.send(self.email, message) ``` **GOOD**: **正面示例**: ```python class User: def __init__(self, name, email): self.name = name self.email = email class UserRepository: def save(self, user): db.execute(f"INSERT INTO users...") class EmailService: def send_email(self, email, message): smtp.send(email, message) ``` --- ### O - Open/Closed Principle ### O——开闭原则 **Open for extension, closed for modification.** **对扩展开放,对修改关闭。** **BAD**: **反面示例**: ```python class PaymentProcessor: def process(self, payment_type, amount): if payment_type == "credit_card": # Credit card processing pass elif payment_type == "paypal": # PayPal processing pass # Adding new type requires modifying this function! ``` **GOOD**: **正面示例**: ```python from abc import ABC, abstractmethod class PaymentMethod(ABC): @abstractmethod def process(self, amount): pass class CreditCardPayment(PaymentMethod): def process(self, amount): # Credit card processing pass class PayPalPayment(PaymentMethod): def process(self, amount): # PayPal processing pass class PaymentProcessor: def process(self, payment_method: PaymentMethod, amount): payment_method.process(amount) ``` --- ### L - Liskov Substitution Principle ### L——里氏替换原则 **Subclasses should be substitutable for their base classes.** **子类应该可以替换其基类。** **BAD**: **反面示例**: ```python class Bird: def fly(self): print("Flying") class Penguin(Bird): def fly(self): raise Exception("Penguins can't fly!") ``` **GOOD**: **正面示例**: ```python class Bird: def move(self): pass class FlyingBird(Bird): def move(self): self.fly() def fly(self): print("Flying") class Penguin(Bird): def move(self): self.swim() def swim(self): print("Swimming") ``` --- ### I - Interface Segregation Principle ### I——接口隔离原则 **Clients should not depend on interfaces they don't use.** **客户端不应该依赖它们不使用的方法。** **BAD**: **反面示例**: ```python class Worker(ABC): @abstractmethod def work(self): pass @abstractmethod def eat(self): pass class Robot(Worker): def work(self): print("Working") def eat(self): # Robots don't eat! raise NotImplementedError ``` **GOOD**: **正面示例**: ```python class Workable(ABC): @abstractmethod def work(self): pass class Eatable(ABC): @abstractmethod def eat(self): pass class Human(Workable, Eatable): def work(self): print("Working") def eat(self): print("Eating") class Robot(Workable): def work(self): print("Working") ``` --- ### D - Dependency Inversion Principle ### D——依赖倒置原则 **Depend on abstractions, not concretions.** **依赖抽象,而非具体实现。** **BAD**: **反面示例**: ```python class MySQLDatabase: def save(self, data): pass class UserService: def __init__(self): self.db = MySQLDatabase() # Tightly coupled def save_user(self, user): self.db.save(user) ``` **GOOD**: **正面示例**: ```python class Database(ABC): @abstractmethod def save(self, data): pass class MySQLDatabase(Database): def save(self, data): pass class PostgresDatabase(Database): def save(self, data): pass class UserService: def __init__(self, database: Database): self.db = database # Depends on abstraction def save_user(self, user): self.db.save(user) ``` --- ## Code Smells to Avoid ## 需要避免的代码坏味 ### 1. Long Parameter List ### 1. 过长的参数列表 ```python # BAD def create_user(name, email, phone, address, city, state, zip, country): pass # GOOD class UserData: def __init__(self, name, email, contact_info, address): pass def create_user(user_data: UserData): pass ``` ### 2. Primitive Obsession ### 2. 基本类型偏执 ```python # BAD def calculate_shipping(width, height, depth, weight): pass # GOOD class Dimensions: def __init__(self, width, height, depth): self.width = width self.height = height self.depth = depth class Package: def __init__(self, dimensions, weight): self.dimensions = dimensions self.weight = weight def calculate_shipping(package: Package): pass ``` ### 3. Feature Envy ### 3. 依恋情结 ```python # BAD - Method in class A uses mostly data from class B class Order: def calculate_total(self, customer): discount = customer.discount_rate points = customer.loyalty_points # Uses customer data extensively pass # GOOD - Move method to class B class Customer: def calculate_order_discount(self, order): discount = self.discount_rate points = self.loyalty_points # Uses own data pass ``` --- ## Testing Best Practices ## 测试最佳实践 ### 1. AAA Pattern (Arrange-Act-Assert) ### 1. AAA 模式(Arrange-Act-Assert) ```python def test_user_creation(): # Arrange name = "Alice" email = "alice@example.com" # Act user = User(name, email) # Assert assert user.name == name assert user.email == email ``` ### 2. One Assertion Per Test (guideline) ### 2. 每个测试一个断言(指导原则) ```python # AVOID multiple unrelated assertions def test_user(): user = User("Alice", "alice@example.com") assert user.name == "Alice" assert user.email == "alice@example.com" assert user.is_valid() assert user.created_at is not None # PREFER focused tests def test_user_name(): user = User("Alice", "alice@example.com") assert user.name == "Alice" def test_user_email(): user = User("Alice", "alice@example.com") assert user.email == "alice@example.com" ``` ### 3. Test Names Should Be Descriptive ### 3. 测试名称应具有描述性 ```python # BAD def test_user(): pass # GOOD def test_user_creation_with_valid_email_succeeds(): pass def test_user_creation_with_invalid_email_raises_error(): pass ``` --- ## Refactoring Checklist ## 重构检查清单 When you see code that needs improvement: 当你看到需要改进的代码时: 1. **Is it tested?** If not, write tests first 2. **One change at a time** - Refactor incrementally 3. **Run tests after each change** - Ensure nothing breaks 4. **Commit frequently** - Small, focused commits 5. **Don't change behavior** - Refactoring should preserve functionality 1. **有测试吗?** 如果没有,先编写测试 2. **一次只改一处**——增量式重构 3. **每次修改后运行测试**——确保没有破坏任何功能 4. **频繁提交**——小而专注的提交 5. **不改变行为**——重构应保留原有功能 --- ## Key Takeaways ## 关键要点 1. **Names matter** - Spend time choosing good names 2. **Functions should be small** - Aim for 10-20 lines 3. **One responsibility** - Each function/class does one thing well 4. **DRY** - Don't repeat yourself 5. **SOLID** - Follow the five SOLID principles 6. **Early returns** - Reduce nesting with guard clauses 7. **Comment why** - Not what (code shows what) 8. **Test** - Write tests, refactor with confidence 1. **命名很重要**——花时间选择好的名称 2. **函数应该短小**——目标是 10–20 行 3. **单一职责**——每个函数/类做好一件事 4. **DRY**——不要重复自己 5. **SOLID**——遵循五大 SOLID 原则 6. **提前返回**——使用卫语句减少嵌套 7. **注释说明「为什么」**——而非「是什么」(代码本身就展示了是什么) 8. **测试**——编写测试,自信重构 **Remember**: Clean code is not about perfection—it's about making code easier to read, maintain, and extend! **记住**:整洁代码不在于追求完美——而在于让代码更易读、更易维护、更易扩展!