开篇:为什么要追求高内聚低耦合?
对零基础开发者来说,高内聚低耦合是 Python 项目「长治久安」的核心保障------ 它能让你的项目:
- 易维护:修改一个功能不会影响其他功能
- 易扩展:新增功能无需重构整个项目
- 易测试:单个模块可以独立测试
- 易协作:多开发者可以同时开发不同模块
本文将从零基础的视角 ,系统讲解七大设计原则 和拓展技巧,并结合 Python 项目实战,教你如何在实际开发中做到高内聚低耦合。
一、基础概念:什么是高内聚低耦合?
1.1 内聚性(Cohesion)
内聚性是衡量一个模块内部功能关联性的指标------ 内聚性越高,模块内部的功能越集中、越单一。
1.1.1 内聚性的类型(从低到高)
- 偶然内聚:模块内的功能没有任何关联(最差)
- 逻辑内聚:模块内的功能按逻辑分组(如将所有输入功能放在一个模块)
- 时间内聚:模块内的功能在同一时间执行(如初始化模块)
- 过程内聚:模块内的功能按顺序执行(如数据处理流程)
- 通信内聚:模块内的功能操作同一数据(较好)
- 功能内聚:模块内的功能实现一个单一的、明确的功能(最好)
1.1.2 Python 示例(低内聚 vs 高内聚)
# 低内聚:一个模块实现多个不相关的功能
def bad_module():
# 功能1:读取文件
with open("data.txt") as f:
data = f.read()
# 功能2:发送邮件
import smtplib
server = smtplib.SMTP("smtp.qq.com", 587)
server.sendmail("sender@qq.com", "receiver@qq.com", data)
# 功能3:生成报告
with open("report.txt", "w") as f:
f.write("Report:\n" + data)
# 高内聚:三个模块分别实现单一功能
def read_file(filename):
# 仅实现读取文件的功能
with open(filename) as f:
return f.read()
def send_email(data):
# 仅实现发送邮件的功能
import smtplib
server = smtplib.SMTP("smtp.qq.com", 587)
server.sendmail("sender@qq.com", "receiver@qq.com", data)
def generate_report(data):
# 仅实现生成报告的功能
with open("report.txt", "w") as f:
f.write("Report:\n" + data)
1.2 耦合性(Coupling)
耦合性是衡量模块之间依赖程度的指标------ 耦合性越低,模块之间的依赖越弱。
1.2.1 耦合性的类型(从高到低)
- 内容耦合:一个模块直接修改另一个模块的内容(最差)
- 公共耦合:多个模块共享全局数据(较差)
- 外部耦合:多个模块依赖同一外部资源(如数据库)
- 控制耦合:一个模块传递控制信息给另一个模块
- 标记耦合:一个模块传递数据结构给另一个模块
- 数据耦合:一个模块传递简单数据给另一个模块(较好)
- 非直接耦合:模块之间通过接口通信(最好)
1.2.2 Python 示例(高耦合 vs 低耦合)
# 高耦合:模块之间直接依赖
class HighCouplingModule:
def __init__(self):
self.database = "mysql://localhost:3306/test" # 直接依赖数据库
self.server = "http://localhost:8000" # 直接依赖服务器
def process_data(self):
# 直接操作数据库和服务器
import mysql.connector
conn = mysql.connector.connect(self.database)
cursor = conn.cursor()
cursor.execute("SELECT * FROM data")
data = cursor.fetchall()
import requests
requests.post(self.server, json=data)
# 低耦合:模块之间通过接口通信
class DatabaseModule:
def __init__(self, database_url):
self.database_url = database_url
def get_data(self):
import mysql.connector
conn = mysql.connector.connect(self.database_url)
cursor = conn.cursor()
cursor.execute("SELECT * FROM data")
return cursor.fetchall()
class ServerModule:
def __init__(self, server_url):
self.server_url = server_url
def send_data(self, data):
import requests
requests.post(self.server_url, json=data)
class LowCouplingModule:
def __init__(self, database_module, server_module):
# 通过接口依赖,而非直接依赖具体实现
self.database_module = database_module
self.server_module = server_module
def process_data(self):
data = self.database_module.get_data()
self.server_module.send_data(data)
二、七大设计原则:高内聚低耦合的核心准则
七大设计原则是面向对象设计的核心准则,也是实现高内聚低耦合的基础。
2.1 单一职责原则(Single Responsibility Principle, SRP)
定义 :一个模块或类只负责一个单一的功能。核心:「一个类应该只有一个改变的理由」。
2.1.1 Python 实战应用:用户管理系统
# 违反单一职责原则:一个类负责用户管理和邮件发送
class BadUserManager:
def add_user(self, user):
# 1. 保存用户到数据库
print(f"Saved user: {user}")
# 2. 发送欢迎邮件
print(f"Sent welcome email to: {user['email']}")
def delete_user(self, user_id):
# 1. 从数据库删除用户
print(f"Deleted user: {user_id}")
# 2. 发送通知邮件
print(f"Sent deletion notification to user: {user_id}")
# 遵循单一职责原则:两个类分别负责用户管理和邮件发送
class UserManager:
def add_user(self, user):
print(f"Saved user: {user}")
def delete_user(self, user_id):
print(f"Deleted user: {user_id}")
class EmailService:
def send_welcome_email(self, email):
print(f"Sent welcome email to: {email}")
def send_deletion_email(self, user_id):
print(f"Sent deletion notification to user: {user_id}")
# 使用示例
user_manager = UserManager()
email_service = EmailService()
user = {"name": "Tom", "email": "tom@example.com"}
user_manager.add_user(user)
email_service.send_welcome_email(user["email"])
2.2 开放封闭原则(Open/Closed Principle, OCP)
定义 :软件实体(类、模块、函数)应该对扩展开放,对修改封闭 。核心:「扩展功能用新增代码,而不是修改已有代码」。
2.2.1 Python 实战应用:支付系统
# 违反开放封闭原则:新增支付方式需要修改现有代码
class BadPaymentSystem:
def process_payment(self, payment_type, amount):
if payment_type == "alipay":
print(f"Processed Alipay payment: {amount}")
elif payment_type == "wechat":
print(f"Processed WeChat payment: {amount}")
# 新增支付方式需要添加新的elif分支
# 遵循开放封闭原则:新增支付方式只需扩展新类
from abc import ABC, abstractmethod
# 抽象支付类
class Payment(ABC):
@abstractmethod
def process(self, amount):
pass
# 支付宝支付类
class AlipayPayment(Payment):
def process(self, amount):
print(f"Processed Alipay payment: {amount}")
# 微信支付类
class WeChatPayment(Payment):
def process(self, amount):
print(f"Processed WeChat payment: {amount}")
# 银联支付类(新增,无需修改现有代码)
class UnionPayPayment(Payment):
def process(self, amount):
print(f"Processed UnionPay payment: {amount}")
# 支付系统(对修改封闭,对扩展开放)
class PaymentSystem:
def process_payment(self, payment: Payment, amount):
payment.process(amount)
# 使用示例
payment_system = PaymentSystem()
alipay = AlipayPayment()
payment_system.process_payment(alipay, 100) # Processed Alipay payment: 100
unionpay = UnionPayPayment()
payment_system.process_payment(unionpay, 200) # Processed UnionPay payment: 200
2.3 里氏替换原则(Liskov Substitution Principle, LSP)
定义 :子类对象应该能够替换父类对象而不影响程序的正确性。核心:「子类必须保持父类的行为契约」。
2.3.1 Python 实战应用:图形绘制系统
# 违反里氏替换原则:子类改变了父类的行为
class BadShape:
def calculate_area(self):
pass
class BadRectangle(BadShape):
def __init__(self, width, height):
self.width = width
self.height = height
def calculate_area(self):
return self.width * self.height
class BadSquare(BadRectangle):
def __init__(self, side):
super().__init__(side, side)
# 违反里氏替换原则:修改了父类的属性设置
def set_width(self, width):
self.width = width
self.height = width # 正方形的宽高必须相等
def set_height(self, height):
self.width = height
self.height = height # 正方形的宽高必须相等
# 遵循里氏替换原则:保持父类的行为契约
class Shape(ABC):
@abstractmethod
def calculate_area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self._width = width
self._height = height
def calculate_area(self):
return self._width * self._height
def set_width(self, width):
self._width = width
def set_height(self, height):
self._height = height
class Square(Shape):
def __init__(self, side):
self._side = side
def calculate_area(self):
return self._side * self._side
def set_side(self, side):
self._side = side
# 使用示例
def print_area(shape):
print(f"Area: {shape.calculate_area()}")
rect = Rectangle(2, 3)
print_area(rect) # Area: 6
square = Square(2)
print_area(square) # Area: 4
2.4 依赖倒置原则(Dependency Inversion Principle, DIP)
定义 :高层模块不应该依赖低层模块,两者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。核心:「依赖接口,而非具体实现」。
2.4.1 Python 实战应用:日志系统
# 违反依赖倒置原则:高层模块依赖低层模块的具体实现
class BadFileLogger:
def log(self, message):
with open("log.txt", "a") as f:
f.write(message + "\n")
class BadApp:
def __init__(self):
self.logger = BadFileLogger() # 依赖具体实现
def run(self):
self.logger.log("App started")
# 遵循依赖倒置原则:高层模块依赖抽象
class Logger(ABC):
@abstractmethod
def log(self, message):
pass
class FileLogger(Logger):
def log(self, message):
with open("log.txt", "a") as f:
f.write(message + "\n")
class ConsoleLogger(Logger):
def log(self, message):
print(message)
class App:
def __init__(self, logger: Logger):
self.logger = logger # 依赖抽象接口
def run(self):
self.logger.log("App started")
# 使用示例
file_logger = FileLogger()
app1 = App(file_logger)
app1.run() # 写入到log.txt
console_logger = ConsoleLogger()
app2 = App(console_logger)
app2.run() # 打印到控制台
2.5 接口隔离原则(Interface Segregation Principle, ISP)
定义 :客户端不应该依赖它不需要的接口。核心:「将大接口拆分为小接口,每个接口只负责一个功能」。
2.5.1 Python 实战应用:打印机系统
# 违反接口隔离原则:一个大接口包含所有功能
class BadPrinterInterface(ABC):
@abstractmethod
def print(self, content):
pass
@abstractmethod
def scan(self, content):
pass
@abstractmethod
def fax(self, content):
pass
class BadSimplePrinter(BadPrinterInterface):
def print(self, content):
print(f"Printed: {content}")
# 违反接口隔离原则:实现了不需要的功能
def scan(self, content):
raise NotImplementedError("Scan not supported")
def fax(self, content):
raise NotImplementedError("Fax not supported")
# 遵循接口隔离原则:拆分接口为小接口
class Printable(ABC):
@abstractmethod
def print(self, content):
pass
class Scannable(ABC):
@abstractmethod
def scan(self, content):
pass
class Faxable(ABC):
@abstractmethod
def fax(self, content):
pass
# 简单打印机(仅支持打印)
class SimplePrinter(Printable):
def print(self, content):
print(f"Printed: {content}")
# 多功能打印机(支持打印、扫描、传真)
class MultiFunctionPrinter(Printable, Scannable, Faxable):
def print(self, content):
print(f"Printed: {content}")
def scan(self, content):
print(f"Scanned: {content}")
def fax(self, content):
print(f"Faxed: {content}")
# 使用示例
simple_printer = SimplePrinter()
simple_printer.print("Hello World") # Printed: Hello World
multi_printer = MultiFunctionPrinter()
multi_printer.scan("Document") # Scanned: Document
2.6 迪米特法则(Law of Demeter, LoD)
定义 :一个对象应该对其他对象有最少的了解。核心:「只和直接的朋友通信」。
2.6.1 Python 实战应用:订单系统
# 违反迪米特法则:一个对象了解其他对象的内部结构
class BadCustomer:
def __init__(self, name, address):
self.name = name
self.address = address # Address对象
class BadOrder:
def __init__(self, customer, product):
self.customer = customer
self.product = product
def ship_order(self):
# 违反迪米特法则:了解Customer的内部结构Address
print(f"Shipped to: {self.customer.address.street}, {self.customer.address.city}")
# 遵循迪米特法则:减少对象之间的了解
class Customer:
def __init__(self, name, address):
self.name = name
self.address = address
# 提供获取完整地址的方法,隐藏内部结构
def get_full_address(self):
return f"{self.address.street}, {self.address.city}"
class Order:
def __init__(self, customer, product):
self.customer = customer
self.product = product
def ship_order(self):
# 只调用Customer的公共方法,不了解其内部结构
print(f"Shipped to: {self.customer.get_full_address()}")
# 使用示例
class Address:
def __init__(self, street, city):
self.street = street
self.city = city
address = Address("123 Main St", "Beijing")
customer = Customer("Tom", address)
order = Order(customer, "Laptop")
order.ship_order() # Shipped to: 123 Main St, Beijing
2.7 合成复用原则(Composite Reuse Principle, CRP)
定义 :尽量使用合成 / 聚合,而不是继承来实现代码复用。核心:「优先使用组合,而非继承」。
2.7.1 Python 实战应用:汽车系统
# 违反合成复用原则:使用继承实现代码复用
class BadVehicle:
def start_engine(self):
print("Engine started")
class BadCar(BadVehicle):
def __init__(self, brand):
self.brand = brand
def drive(self):
self.start_engine()
print(f"{self.brand} car driving")
# 遵循合成复用原则:使用组合实现代码复用
class Engine:
def start(self):
print("Engine started")
class Car:
def __init__(self, brand):
self.brand = brand
self.engine = Engine() # 组合Engine对象
def drive(self):
self.engine.start()
print(f"{self.brand} car driving")
# 使用示例
car = Car("Toyota")
car.drive() # Engine started; Toyota car driving
三、拓展技巧:高内聚低耦合的实战方法
除了七大设计原则,还有一些实战技巧可以帮助你实现高内聚低耦合。
3.1 模块化设计
模块化设计是将一个大项目拆分为多个小模块的方法,每个模块负责一个单一的功能。
3.1.1 Python 模块化的实现
- 模块 :一个
.py文件就是一个模块 - 包 :包含多个模块的目录,目录下必须有
__init__.py文件 - 接口 :通过
__all__变量或抽象类定义模块的接口
3.1.2 Python 实战应用:电商系统的模块化设计
ecommerce/ # 包
├── __init__.py # 包初始化文件
├── user/ # 用户模块
│ ├── __init__.py
│ ├── models.py # 用户模型
│ └── service.py # 用户服务
├── product/ # 商品模块
│ ├── __init__.py
│ ├── models.py # 商品模型
│ └── service.py # 商品服务
├── order/ # 订单模块
│ ├── __init__.py
│ ├── models.py # 订单模型
│ └── service.py # 订单服务
└── payment/ # 支付模块
├── __init__.py
├── models.py # 支付模型
└── service.py # 支付服务
3.2 依赖注入
依赖注入是将模块的依赖传递给模块的方法,而不是模块自己创建依赖。
3.2.1 Python 依赖注入的实现
- 构造函数注入:在构造函数中传递依赖
- 方法注入:在方法中传递依赖
- 属性注入:通过属性设置依赖
3.2.2 Python 实战应用:依赖注入的实现
# 构造函数注入
class UserService:
def __init__(self, user_repository):
self.user_repository = user_repository
def get_user(self, user_id):
return self.user_repository.get(user_id)
# 方法注入
class UserService:
def get_user(self, user_id, user_repository):
return user_repository.get(user_id)
# 属性注入
class UserService:
def __init__(self):
self.user_repository = None
def set_user_repository(self, user_repository):
self.user_repository = user_repository
def get_user(self, user_id):
return self.user_repository.get(user_id)
3.3 事件驱动架构
事件驱动架构是模块之间通过事件通信的方法,模块不需要直接依赖其他模块。
3.3.1 Python 事件驱动的实现
- 使用内置的
asyncio模块 - 使用第三方库如
pydispatcher或blinker
3.3.2 Python 实战应用:事件驱动的用户注册
from blinker import signal
# 定义事件
user_registered = signal("user-registered")
# 定义事件处理函数
@user_registered.connect
def send_welcome_email(user):
print(f"Sent welcome email to: {user['email']}")
@user_registered.connect
def log_user_registration(user):
print(f"Logged user registration: {user['name']}")
# 定义用户注册服务
class UserService:
def register_user(self, user):
print(f"Registered user: {user['name']}")
# 触发事件
user_registered.send(user)
# 使用示例
user_service = UserService()
user = {"name": "Tom", "email": "tom@example.com"}
user_service.register_user(user)
# 输出:
# Registered user: Tom
# Sent welcome email to: tom@example.com
# Logged user registration: Tom
安装依赖 :pip install blinker
3.4 中间件模式
中间件模式是在请求处理流程中插入中间层的方法,每个中间层负责一个单一的功能。
3.4.1 Python 中间件的实现
# 定义中间件接口
class Middleware:
def __init__(self, next_middleware=None):
self.next_middleware = next_middleware
def handle(self, request):
# 处理请求
if self.next_middleware:
return self.next_middleware.handle(request)
return request
# 定义具体中间件
class AuthenticationMiddleware(Middleware):
def handle(self, request):
print(f"Authenticated request: {request}")
return super().handle(request)
class LoggingMiddleware(Middleware):
def handle(self, request):
print(f"Logged request: {request}")
return super().handle(request)
class AuthorizationMiddleware(Middleware):
def handle(self, request):
print(f"Authorized request: {request}")
return super().handle(request)
# 使用示例
request = {"url": "/api/user", "method": "GET", "user_id": 123}
# 创建中间件链
auth_middleware = AuthenticationMiddleware()
log_middleware = LoggingMiddleware(auth_middleware)
authz_middleware = AuthorizationMiddleware(log_middleware)
# 处理请求
response = authz_middleware.handle(request)
# 输出:
# Authorized request: {'url': '/api/user', 'method': 'GET', 'user_id': 123}
# Logged request: {'url': '/api/user', 'method': 'GET', 'user_id': 123}
# Authenticated request: {'url': '/api/user', 'method': 'GET', 'user_id': 123}
3.5 装饰器模式
装饰器模式是在不修改原有代码的情况下扩展功能的方法,是 Python 实现开放封闭原则的核心技巧。
3.5.1 Python 装饰器的实现
# 定义装饰器
def log_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling function: {func.__name__}")
result = func(*args, **kwargs)
print(f"Function {func.__name__} returned: {result}")
return result
return wrapper
# 使用装饰器
@log_decorator
def add(a, b):
return a + b
# 使用示例
result = add(1, 2)
# 输出:
# Calling function: add
# Function add returned: 3
3.6 配置分离
配置分离是将配置信息从代码中分离出来的方法,避免代码中出现硬编码的配置。
3.6.1 Python 配置分离的实现
- 使用
.ini或.json文件 - 使用环境变量
- 使用第三方库如
python-dotenv或pyyaml
3.6.2 Python 实战应用:配置分离的实现
# 使用python-dotenv读取环境变量
# 安装依赖:pip install python-dotenv
# 创建.env文件
# DATABASE_URL=mysql://localhost:3306/test
# SECRET_KEY=abc123
from dotenv import load_dotenv
import os
load_dotenv() # 加载.env文件
# 读取配置
DATABASE_URL = os.getenv("DATABASE_URL")
SECRET_KEY = os.getenv("SECRET_KEY")
print(f"Database URL: {DATABASE_URL}")
print(f"Secret Key: {SECRET_KEY}")
四、Python 项目实战:高内聚低耦合的完整实现
4.1 项目需求
开发一个电商订单管理系统,要求实现以下功能:
- 用户管理:注册、登录、查询
- 商品管理:查询、添加、修改
- 订单管理:创建、查询、取消
- 支付管理:支付宝、微信支付
4.2 项目架构
ecommerce_order_system/
├── __init__.py
├── config/ # 配置模块
│ ├── __init__.py
│ └── config.py
├── models/ # 数据模型模块
│ ├── __init__.py
│ ├── user.py
│ ├── product.py
│ ├── order.py
│ └── payment.py
├── repositories/ # 数据访问模块
│ ├── __init__.py
│ ├── user_repository.py
│ ├── product_repository.py
│ └── order_repository.py
├── services/ # 业务逻辑模块
│ ├── __init__.py
│ ├── user_service.py
│ ├── product_service.py
│ ├── order_service.py
│ └── payment_service.py
├── middlewares/ # 中间件模块
│ ├── __init__.py
│ ├── auth_middleware.py
│ └── log_middleware.py
└── main.py # 入口文件
4.3 核心代码实现
4.3.1 配置模块(config/config.py)
from dotenv import load_dotenv
import os
load_dotenv()
class Config:
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///:memory:")
SECRET_KEY = os.getenv("SECRET_KEY", "default-secret-key")
DEBUG = os.getenv("DEBUG", "True") == "True"
4.3.2 数据模型模块(models/order.py)
class Order:
def __init__(self, order_id, user_id, product_id, amount, status="pending"):
self.order_id = order_id
self.user_id = user_id
self.product_id = product_id
self.amount = amount
self.status = status
def to_dict(self):
return {
"order_id": self.order_id,
"user_id": self.user_id,
"product_id": self.product_id,
"amount": self.amount,
"status": self.status
}
4.3.3 数据访问模块(repositories/order_repository.py)
from models.order import Order
class OrderRepository:
def __init__(self):
# 模拟数据库
self.orders = {}
def create_order(self, order):
self.orders[order.order_id] = order
return order
def get_order(self, order_id):
return self.orders.get(order_id)
def cancel_order(self, order_id):
if order_id in self.orders:
self.orders[order_id].status = "cancelled"
return self.orders[order_id]
return None
4.3.4 业务逻辑模块(services/order_service.py)
from repositories.order_repository import OrderRepository
from repositories.user_repository import UserRepository
from repositories.product_repository import ProductRepository
from services.payment_service import PaymentService
from models.order import Order
class OrderService:
def __init__(self, order_repo, user_repo, product_repo, payment_service):
self.order_repo = order_repo
self.user_repo = user_repo
self.product_repo = product_repo
self.payment_service = payment_service
def create_order(self, user_id, product_id, amount):
# 验证用户和商品是否存在
user = self.user_repo.get_user(user_id)
product = self.product_repo.get_product(product_id)
if not user or not product:
raise ValueError("Invalid user or product")
# 创建订单
order_id = f"order_{len(self.order_repo.orders) + 1}"
order = Order(order_id, user_id, product_id, amount)
order = self.order_repo.create_order(order)
# 处理支付
self.payment_service.process_payment(order.amount)
return order
def cancel_order(self, order_id):
return self.order_repo.cancel_order(order_id)
4.3.5 中间件模块(middlewares/auth_middleware.py)
class AuthMiddleware:
def __init__(self, next_handler):
self.next_handler = next_handler
def handle(self, request):
# 验证用户身份
if "user_id" not in request:
raise ValueError("Unauthorized")
return self.next_handler.handle(request)
4.3.6 入口文件(main.py)
from config.config import Config
from repositories.user_repository import UserRepository
from repositories.product_repository import ProductRepository
from repositories.order_repository import OrderRepository
from services.user_service import UserService
from services.product_service import ProductService
from services.order_service import OrderService
from services.payment_service import AlipayPaymentService
from middlewares.auth_middleware import AuthMiddleware
from middlewares.log_middleware import LogMiddleware
# 初始化依赖
user_repo = UserRepository()
product_repo = ProductRepository()
order_repo = OrderRepository()
payment_service = AlipayPaymentService()
log_middleware = LogMiddleware()
auth_middleware = AuthMiddleware(log_middleware)
# 初始化服务
user_service = UserService(user_repo)
product_service = ProductService(product_repo)
order_service = OrderService(order_repo, user_repo, product_repo, payment_service)
# 测试用户注册
user = user_service.register_user({"name": "Tom", "email": "tom@example.com"})
print(f"Registered user: {user.to_dict()}")
# 测试商品添加
product = product_service.add_product({"name": "Laptop", "price": 9999})
print(f"Added product: {product.to_dict()}")
# 测试订单创建
order = order_service.create_order(user.user_id, product.product_id, 9999)
print(f"Created order: {order.to_dict()}")
# 测试订单取消
cancelled_order = order_service.cancel_order(order.order_id)
print(f"Cancelled order: {cancelled_order.to_dict()}")
4.4 项目特点
- 高内聚:每个模块负责一个单一的功能
- 低耦合:模块之间通过接口通信,依赖注入实现
- 可扩展:新增支付方式只需扩展 Payment 接口
- 可维护:修改一个模块不会影响其他模块
- 可测试:单个模块可以独立测试
五、零基础避坑指南
5.1 不要过度设计
不要为了实现高内聚低耦合而过度设计------ 先实现功能,再逐步优化。
5.2 不要滥用继承
优先使用组合,而非继承 ------ 继承会增加模块之间的耦合性。
5.3 不要使用全局变量
全局变量会导致公共耦合------ 尽量使用参数传递或依赖注入。
5.4 不要硬编码配置
将配置信息分离到配置文件或环境变量中 ------ 避免代码修改。
5.5 不要违反单一职责原则
一个模块或类只负责一个单一的功能 ------ 避免模块变得臃肿。
六、总结:高内聚低耦合的实现路径
6.1 设计阶段
- 需求分析:明确项目的功能和模块划分
- 模块设计:将项目拆分为多个高内聚的模块
- 接口设计:定义模块之间的接口
- 依赖设计:使用依赖注入或组合实现模块之间的依赖
6.2 开发阶段
- 遵循七大设计原则:单一职责、开放封闭、里氏替换、依赖倒置、接口隔离、迪米特法则、合成复用
- 使用拓展技巧:模块化设计、依赖注入、事件驱动、中间件模式、装饰器模式、配置分离
- 代码审查:确保代码符合高内聚低耦合的要求
6.3 维护阶段
- 持续优化:定期检查和优化模块之间的耦合性
- 测试:单个模块独立测试,确保修改不会影响其他模块
- 文档:维护模块的接口文档,确保新开发者能够快速理解
高内聚低耦合是Python 项目开发的长期目标 ,需要在实践中不断积累和优化。通过遵循七大设计原则和使用拓展技巧,你将能够开发出易维护、易扩展、易测试的高质量 Python 项目。