下面我将通过详细的 Python 代码示例,深入讲解每个面向对象的最佳实践原则。
1. 优先使用组合而非继承 问题示例(使用继承) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Employee : def __init__ (self, name, salary ): self.name = name self.salary = salary def calculate_bonus (self ): return self.salary * 0.1 class Manager (Employee ): def __init__ (self, name, salary, team_size ): super ().__init__(name, salary) self.team_size = team_size def manage_team (self ): print (f"{self.name} is managing a team of {self.team_size} people" )
解决方案(使用组合) 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 class BonusCalculator : @staticmethod def calculate (salary ): return salary * 0.1 class TeamManager : def __init__ (self, team_size ): self.team_size = team_size def manage (self, name ): print (f"{name} is managing a team of {self.team_size} people" ) class Employee : def __init__ (self, name, salary, bonus_calculator=None ): self.name = name self.salary = salary self.bonus_calculator = bonus_calculator or BonusCalculator() def calculate_bonus (self ): return self.bonus_calculator.calculate(self.salary) class Manager : def __init__ (self, name, salary, team_size ): self.employee = Employee(name, salary) self.team_manager = TeamManager(team_size) def calculate_bonus (self ): return self.employee.calculate_bonus() def manage_team (self ): self.team_manager.manage(self.employee.name) manager = Manager("Alice" , 80000 , 5 ) manager.manage_team() print (f"Bonus: {manager.calculate_bonus()} " )
2. 遵循最小知识原则(迪米特法则) 问题示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Address : def __init__ (self, city, street ): self.city = city self.street = street class Person : def __init__ (self, name, address ): self.name = name self.address = address def get_address (self ): return self.address person = Person("Bob" , Address("Beijing" , "Main St" )) print (person.get_address().city)
解决方案 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Person : def __init__ (self, name, address ): self.name = name self._address = address def get_city (self ): return self._address.city def get_street (self ): return self._address.street person = Person("Bob" , Address("Beijing" , "Main St" )) print (person.get_city())
3. 保持类和方法的小型化 问题示例(大类) 1 2 3 4 5 6 7 8 class ReportGenerator : def generate_report (self, data ): pass
解决方案(分解) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class DataValidator : def validate (self, data ): pass class DataProcessor : def process (self, data ): pass class ReportBuilder : def build (self, processed_data ): pass class ReportSaver : def save (self, report ): pass class ReportGenerator : def __init__ (self ): self.validator = DataValidator() self.processor = DataProcessor() self.builder = ReportBuilder() self.saver = ReportSaver() def generate_report (self, data ): self.validator.validate(data) processed_data = self.processor.process(data) report = self.builder.build(processed_data) self.saver.save(report)
4. 使用有意义的名字 差的名字 1 2 3 4 5 6 def p (d ): return d * 1.1 class M : def c (self, x ): return x * 2
好的名字 1 2 3 4 5 6 def calculate_price_with_tax (price ): return price * 1.1 class ShoppingCart : def calculate_total (self, items ): return sum (item.price for item in items)
5. 合理使用访问修饰符 Python 使用命名约定实现访问控制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class BankAccount : def __init__ (self, owner, balance ): self.owner = owner self._balance = balance self.__secret_code = 123 def deposit (self, amount ): if amount > 0 : self._balance += amount def _validate_amount (self, amount ): return amount > 0 def __generate_statement (self ): return f"Statement for {self.owner} " account = BankAccount("Alice" , 1000 ) print (account.owner) print (account._balance)
6. 避免上帝对象 问题示例 1 2 3 4 5 6 7 8 9 10 11 class GodObject : def __init__ (self ): self.users = [] self.products = [] self.orders = [] def add_user (self, user ): pass def delete_user (self, user_id ): pass def add_product (self, product ): pass def process_order (self, order ): pass
解决方案(分解责任) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class UserManager : def __init__ (self ): self.users = [] def add_user (self, user ): pass def delete_user (self, user_id ): pass class ProductCatalog : def __init__ (self ): self.products = [] def add_product (self, product ): pass class OrderProcessor : def process_order (self, order ): pass class ECommerceSystem : def __init__ (self ): self.user_manager = UserManager() self.product_catalog = ProductCatalog() self.order_processor = OrderProcessor()
7. 合理使用接口和抽象类 Python 使用 abc
模块实现抽象基类:
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 from abc import ABC, abstractmethodclass Renderable (ABC ): @abstractmethod def render (self ): pass class Shape (ABC ): def __init__ (self, color ): self.color = color @abstractmethod def area (self ): pass def describe (self ): print (f"This is a {self.color} shape" ) class Circle (Shape, Renderable): def __init__ (self, color, radius ): super ().__init__(color) self.radius = radius def area (self ): return 3.14 * self.radius ** 2 def render (self ): print (f"Rendering a {self.color} circle with radius {self.radius} " ) circle = Circle("red" , 5 ) circle.describe() print ("Area:" , circle.area())circle.render()
这些最佳实践结合起来,可以帮助你编写出更健壮、更易维护的面向对象 Python 代码。记住要根据具体情况灵活应用这些原则,而不是机械地遵循。