PHP 项目复杂度控制

wen PHP项目 4

PHP 项目复杂度控制

代码层面的复杂度控制

1 函数复杂度控制

// ❌ 高复杂度示例 - 圈复杂度=8
function processOrder(array $order): array {
    if ($order['status'] === 'pending') {
        if ($order['type'] === 'digital') {
            if ($order['paid']) {
                if ($order['stock'] > 0) {
                    // 处理逻辑
                } else {
                    // 无库存
                }
            } else {
                // 未支付
            }
        } else {
            // 实体商品
        }
    } else {
        // 其他状态
    }
}
// ✅ 低复杂度示例 - 用策略模式 + 提前返回
function processOrder(Order $order): array
{
    $handler = new OrderHandlerFactory()->create($order->getType());
    return $handler->process($order);
}

2 方法拆分原则

// ❌ 单一方法做太多事情
function handleUserRegistration(array $data): void
{
    // 验证数据
    // 处理头像上传
    // 创建用户
    // 发送通知
    // 记录日志
}
// ✅ 拆分为独立职责
class UserRegistrationService
{
    public function register(RegistrationData $data): User
    {
        $this->validator->validate($data);
        $user = $this->createUser($data);
        $this->uploadAvatar($data->getAvatar());
        $this->sendWelcomeNotification($user);
        $this->logger->info('User registered', ['user_id' => $user->id]);
        return $user;
    }
    private function createUser(RegistrationData $data): User
    {
        // 仅负责创建用户
    }
}

架构层面的复杂度控制

1 依赖注入

// ❌ 直接在类内部创建依赖
class OrderService
{
    private $repository;
    public function __construct()
    {
        $this->repository = new OrderRepository();
    }
}
// ✅ 依赖注入
class OrderService
{
    private OrderRepositoryInterface $repository;
    private NotificationServiceInterface $notifier;
    public function __construct(
        OrderRepositoryInterface $repository,
        NotificationServiceInterface $notifier
    ) {
        $this->repository = $repository;
        $this->notifier = $notifier;
    }
}

2 分层架构

// 目录结构示例
app/
├── Controllers/        # 控制器层 - 处理HTTP请求
├── Services/           # 服务层 - 业务逻辑
├── Repositories/       # 仓储层 - 数据访问
├── Models/             # 模型层 - 数据实体
├── DTOs/              # 数据传输对象
├── Exceptions/         # 异常处理
└── Contracts/          # 接口定义

测试复杂度控制

1 单元测试示例

// ❌ 测试覆盖过多功能
class OrderServiceTest extends TestCase
{
    public function testOrderProcessing()
    {
        // 测试支付、库存、通知等多个功能
    }
}
// ✅ 单一职责测试
class OrderServiceTest extends TestCase
{
    /** @test */
    public function it_calculates_order_total_correctly()
    {
        $order = $this->createOrder([
            'items' => [['price' => 100, 'qty' => 2]]
        ]);
        $this->assertEquals(200, $order->getTotal());
    }
    /** @test */
    public function it_applies_discount_when_total_exceeds_threshold()
    {
        // 只测试折扣逻辑
    }
}

重构复杂度控制

1 识别需要重构的信号

// 信号1: 类过于庞大
class GrandService {
    private $methods = [];
    // 包含超过500行代码
}
// 信号2: 过长的参数列表
function createUser(
    string $name,
    string $email,
    string $phone,
    string $address,
    bool $isAdmin,
    bool $isVerified,
    array $permissions,
    // ... 越来越多的参数
): User {}
// 重构为参数对象
class UserCreationData
{
    public string $name;
    public string $email;
    public ?string $phone;
    public ?string $address;
    public bool $isAdmin = false;
}
function createUser(UserCreationData $data): User {}

2 使用设计模式控制复杂度

// 策略模式控制业务逻辑复杂度
interface PaymentStrategy
{
    public function pay(Order $order): bool;
}
class AlipayStrategy implements PaymentStrategy
{
    public function pay(Order $order): bool
    {
        // 支付宝支付逻辑
    }
}
class WechatPayStrategy implements PaymentStrategy
{
    public function pay(Order $order): bool
    {
        // 微信支付逻辑
    }
}
class PaymentContext
{
    public function __construct(
        private PaymentStrategy $strategy
    ) {}
    public function executePayment(Order $order): bool
    {
        return $this->strategy->pay($order);
    }
}

代码质量工具

1 PHP CodeSniffer 配置

<!-- phpcs.xml -->
<?xml version="1.0"?>
<ruleset name="Project Rules">
    <description>Project coding standards</description>
    <!-- 不同规则集 -->
    <rule ref="PSR12"/>
    <rule ref="Generic.NamingConventions"/>
    <!-- 复杂度限制 -->
    <rule ref="Generic.Metrics.CyclomaticComplexity">
        <properties>
            <property name="absoluteComplexity" value="10"/>
            <property name="complexity" value="8"/>
        </properties>
    </rule>
</ruleset>

2 PHPStan 配置

# phpstan.neon
parameters:
    level: 8
    analyzers:
        - src
    reportUnmatchedIgnoredErrors: true
    checkMissingIterableValueType: true
    checkGenericClassInNonGenericObjectType: false

持续集成与复杂度监控

# GitHub Actions 示例
name: Code Quality Check
on: [pull_request]
jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
      - name: Install Dependencies
        run: composer install
      - name: Run PHPCS
        run: vendor/bin/phpcs src/
      - name: Run Static Analysis
        run: vendor/bin/phpstan analyse src/ --level=max
      - name: Run Unit Tests
        run: vendor/bin/phpunit --coverage-clover coverage.xml
      - name: Upload Coverage
        uses: codecov/codecov-action@v1

性能复杂度控制

// ❌ N+1查询问题
foreach ($users as $user) {
    $orders = Order::where('user_id', $user->id)->get(); // 每个循环都查询
}
// ✅ 使用预加载
$users = User::with('orders')->get();
foreach ($users as $user) {
    $orders = $user->orders; // 只查询一次
}

总结清单

✅ 代码质量检查清单

  • [ ] 函数不超过30行代码
  • [ ] 圈复杂度不超过10
  • [ ] 类不超过500行代码
  • [ ] 方法参数不超过5个
  • [ ] 每个类只做一件事
  • [ ] 使用依赖注入
  • [ ] 符合PSR-12规范

✅ 架构检查清单

  • [ ] 遵循SOLID原则
  • [ ] 使用单一职责原则
  • [ ] 依赖倒置原则
  • [ ] 使用接口定义契约
  • [ ] 服务层不包含HTTP逻辑

✅ 测试检查清单

  • [ ] 核心业务逻辑有单元测试
  • [ ] 测试覆盖率达到80%以上
  • [ ] 每个测试只测试一个功能
  • [ ] 测试可独立运行

通过持续关注这些维度,并使用合适的工具和规范,可以有效控制PHP项目的复杂度,保持项目的可维护性和可扩展性。

PHP 项目复杂度控制

抱歉,评论功能暂时关闭!