PHP设计模式实战:构建可维护的企业级应用程序架构

2025-09-30 0 333

发布日期:2023年12月1日 | 作者:PHP架构师

设计模式核心概念

设计模式是解决软件设计中常见问题的可重用方案,它们提供了经过验证的解决方案,能够提高代码的可维护性、可扩展性和可重用性。

设计模式的分类

  • 创建型模式:处理对象创建机制(工厂、单例、建造者)
  • 结构型模式:处理对象组合(适配器、装饰器、外观)
  • 行为型模式:处理对象间的通信(观察者、策略、命令)

设计模式的价值

// 不良设计示例 - 紧耦合
class OrderProcessor {
    public function process($order) {
        $emailService = new EmailService();
        $smsService = new SMSService();
        $logger = new FileLogger();
        
        // 业务逻辑与具体实现紧密耦合
        $emailService->sendConfirmation($order);
        $smsService->sendNotification($order);
        $logger->log("Order processed: " . $order->id);
    }
}

// 良好设计示例 - 松耦合
class OrderProcessor {
    public function __construct(
        private NotificationInterface $notifier,
        private LoggerInterface $logger
    ) {}
    
    public function process(Order $order): void {
        // 依赖抽象而非具体实现
        $this->notifier->sendConfirmation($order);
        $this->logger->info("Order processed: {$order->getId()}");
    }
}

高级MVC架构实现

现代MVC架构组件

传统的MVC模式在现代Web应用中需要进一步扩展和优化。

基础控制器实现

abstract class Controller {
    protected function json(array $data, int $statusCode = 200): Response {
        return new Response(
            json_encode($data, JSON_PRETTY_PRINT),
            $statusCode,
            ['Content-Type' => 'application/json']
        );
    }
    
    protected function view(string $template, array $data = []): Response {
        extract($data);
        ob_start();
        include __DIR__ . "/../views/{$template}.php";
        $content = ob_get_clean();
        
        return new Response($content);
    }
}

class ArticleController extends Controller {
    public function __construct(
        private ArticleRepository $articleRepository,
        private AuthorRepository $authorRepository
    ) {}
    
    public function show(int $id): Response {
        $article = $this->articleRepository->find($id);
        
        if (!$article) {
            return $this->json(['error' => 'Article not found'], 404);
        }
        
        return $this->view('article/show', [
            'article' => $article,
            'author' => $this->authorRepository->find($article->getAuthorId())
        ]);
    }
    
    public function create(Request $request): Response {
        $validator = new ArticleValidator($request->getPost());
        
        if (!$validator->validate()) {
            return $this->json([
                'errors' => $validator->getErrors()
            ], 422);
        }
        
        $article = $this->articleRepository->create(
            $validator->getValidatedData()
        );
        
        return $this->json([
            'message' => 'Article created successfully',
            'article' => $article->toArray()
        ], 201);
    }
}

依赖注入容器实战

容器核心实现

依赖注入容器是现代PHP框架的核心,它管理对象的创建和依赖关系。

class Container {
    private array $bindings = [];
    private array $instances = [];
    private array $aliases = [];
    
    public function bind(string $abstract, $concrete = null, bool $shared = false): void {
        if (is_null($concrete)) {
            $concrete = $abstract;
        }
        
        $this->bindings[$abstract] = [
            'concrete' => $concrete,
            'shared' => $shared
        ];
    }
    
    public function singleton(string $abstract, $concrete = null): void {
        $this->bind($abstract, $concrete, true);
    }
    
    public function make(string $abstract) {
        // 检查别名
        $abstract = $this->aliases[$abstract] ?? $abstract;
        
        // 如果是共享实例且已存在,直接返回
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }
        
        $concrete = $this->getConcrete($abstract);
        $object = $this->build($concrete);
        
        // 如果是共享实例,保存起来
        if (isset($this->bindings[$abstract]) && $this->bindings[$abstract]['shared']) {
            $this->instances[$abstract] = $object;
        }
        
        return $object;
    }
    
    private function getConcrete(string $abstract) {
        return $this->bindings[$abstract]['concrete'] ?? $abstract;
    }
    
    private function build($concrete) {
        if (is_callable($concrete)) {
            return $concrete($this);
        }
        
        $reflector = new ReflectionClass($concrete);
        
        if (!$reflector->isInstantiable()) {
            throw new ContainerException("Class {$concrete} is not instantiable");
        }
        
        $constructor = $reflector->getConstructor();
        
        if (is_null($constructor)) {
            return new $concrete;
        }
        
        $parameters = $constructor->getParameters();
        $dependencies = $this->resolveDependencies($parameters);
        
        return $reflector->newInstanceArgs($dependencies);
    }
    
    private function resolveDependencies(array $parameters): array {
        $dependencies = [];
        
        foreach ($parameters as $parameter) {
            $type = $parameter->getType();
            
            if ($type && !$type->isBuiltin()) {
                $dependencies[] = $this->make($type->getName());
            } elseif ($parameter->isDefaultValueAvailable()) {
                $dependencies[] = $parameter->getDefaultValue();
            } else {
                throw new ContainerException(
                    "Cannot resolve dependency: {$parameter->getName()}"
                );
            }
        }
        
        return $dependencies;
    }
}

// 使用示例
$container = new Container();

// 注册服务
$container->singleton(Database::class, function() {
    return new Database('localhost', 'db_name', 'user', 'pass');
});

$container->bind(ArticleRepository::class, EloquentArticleRepository::class);
$container->bind(ArticleService::class);

Repository数据访问模式

Repository模式核心接口

interface RepositoryInterface {
    public function find($id): ?object;
    public function findAll(): array;
    public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null): array;
    public function findOneBy(array $criteria): ?object;
    public function save(object $entity): void;
    public function delete(object $entity): void;
}

interface ArticleRepositoryInterface extends RepositoryInterface {
    public function findByAuthor(Author $author): array;
    public function findPublished(): array;
    public function findByCategory(string $category, int $limit = 10): array;
    public function search(string $query): array;
}

class EloquentArticleRepository implements ArticleRepositoryInterface {
    public function __construct(
        private ArticleModel $model,
        private CacheService $cache
    ) {}
    
    public function find($id): ?Article {
        $cacheKey = "article_{$id}";
        
        return $this->cache->remember($cacheKey, 3600, function() use ($id) {
            $model = $this->model->with(['author', 'comments'])->find($id);
            return $model ? $this->toEntity($model) : null;
        });
    }
    
    public function findByAuthor(Author $author): array {
        return $this->model->where('author_id', $author->getId())
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(fn($model) => $this->toEntity($model))
            ->toArray();
    }
    
    public function search(string $query): array {
        return $this->model->where('title', 'LIKE', "%{$query}%")
            ->orWhere('content', 'LIKE', "%{$query}%")
            ->where('status', 'published')
            ->get()
            ->map(fn($model) => $this->toEntity($model))
            ->toArray();
    }
    
    private function toEntity(ArticleModel $model): Article {
        return new Article(
            id: $model->id,
            title: $model->title,
            content: $model->content,
            authorId: $model->author_id,
            status: $model->status,
            createdAt: new DateTime($model->created_at),
            publishedAt: $model->published_at ? new DateTime($model->published_at) : null
        );
    }
    
    // 实现其他接口方法...
}

观察者模式与事件系统

事件系统核心组件

interface EventListenerInterface {
    public function handle(EventInterface $event): void;
}

interface EventDispatcherInterface {
    public function dispatch(EventInterface $event): void;
    public function addListener(string $eventName, callable $listener): void;
    public function removeListener(string $eventName, callable $listener): void;
}

class EventDispatcher implements EventDispatcherInterface {
    private array $listeners = [];
    
    public function dispatch(EventInterface $event): void {
        $eventName = get_class($event);
        
        if (isset($this->listeners[$eventName])) {
            foreach ($this->listeners[$eventName] as $listener) {
                call_user_func($listener, $event);
            }
        }
    }
    
    public function addListener(string $eventName, callable $listener): void {
        $this->listeners[$eventName][] = $listener;
    }
    
    public function removeListener(string $eventName, callable $listener): void {
        if (isset($this->listeners[$eventName])) {
            $key = array_search($listener, $this->listeners[$eventName], true);
            if ($key !== false) {
                unset($this->listeners[$eventName][$key]);
            }
        }
    }
}

// 定义事件
class ArticlePublishedEvent implements EventInterface {
    public function __construct(
        private Article $article,
        private DateTime $publishedAt
    ) {}
    
    public function getArticle(): Article {
        return $this->article;
    }
    
    public function getPublishedAt(): DateTime {
        return $this->publishedAt;
    }
}

// 事件监听器
class SendArticleNotificationListener implements EventListenerInterface {
    public function __construct(
        private EmailService $emailService,
        private NotificationService $notificationService
    ) {}
    
    public function handle(EventInterface $event): void {
        if (!$event instanceof ArticlePublishedEvent) {
            return;
        }
        
        $article = $event->getArticle();
        
        // 发送邮件通知
        $this->emailService->sendToSubscribers(
            "新文章发布: {$article->getTitle()}",
            $article->getExcerpt()
        );
        
        // 发送推送通知
        $this->notificationService->broadcast(
            'article.published',
            $article->toArray()
        );
    }
}

class UpdateSearchIndexListener implements EventListenerInterface {
    public function handle(EventInterface $event): void {
        if ($event instanceof ArticlePublishedEvent) {
            // 更新搜索引擎索引
            SearchEngine::index($event->getArticle());
        }
    }
}

完整项目:博客系统架构

系统架构概览

class BlogApplication {
    private Container $container;
    private EventDispatcher $dispatcher;
    private Router $router;
    
    public function __construct() {
        $this->container = new Container();
        $this->dispatcher = new EventDispatcher();
        $this->router = new Router();
        
        $this->registerServices();
        $this->registerEvents();
        $this->registerRoutes();
    }
    
    private function registerServices(): void {
        // 数据库连接
        $this->container->singleton(Database::class, function() {
            return new Database(
                getenv('DB_HOST'),
                getenv('DB_NAME'),
                getenv('DB_USER'),
                getenv('DB_PASS')
            );
        });
        
        // 仓库注册
        $this->container->bind(ArticleRepositoryInterface::class, EloquentArticleRepository::class);
        $this->container->bind(AuthorRepositoryInterface::class, EloquentAuthorRepository::class);
        $this->container->bind(CommentRepositoryInterface::class, EloquentCommentRepository::class);
        
        // 服务注册
        $this->container->bind(ArticleService::class);
        $this->container->bind(CommentService::class);
        $this->container->bind(AuthService::class);
    }
    
    private function registerEvents(): void {
        $this->dispatcher->addListener(
            ArticlePublishedEvent::class,
            [new SendArticleNotificationListener(
                $this->container->make(EmailService::class),
                $this->container->make(NotificationService::class)
            ), 'handle']
        );
        
        $this->dispatcher->addListener(
            ArticlePublishedEvent::class,
            [new UpdateSearchIndexListener(), 'handle']
        );
    }
    
    private function registerRoutes(): void {
        $this->router->get('/articles', [ArticleController::class, 'index']);
        $this->router->get('/articles/{id}', [ArticleController::class, 'show']);
        $this->router->post('/articles', [ArticleController::class, 'create']);
        $this->router->put('/articles/{id}', [ArticleController::class, 'update']);
        $this->router->delete('/articles/{id}', [ArticleController::class, 'delete']);
        
        $this->router->post('/articles/{id}/comments', [CommentController::class, 'create']);
        $this->router->get('/authors/{id}/articles', [AuthorController::class, 'articles']);
    }
    
    public function run(): void {
        $request = Request::createFromGlobals();
        $response = $this->router->dispatch($request);
        $response->send();
    }
}

// 服务类实现
class ArticleService {
    public function __construct(
        private ArticleRepositoryInterface $articleRepository,
        private EventDispatcher $dispatcher,
        private CacheService $cache
    ) {}
    
    public function publishArticle(int $articleId): Article {
        $article = $this->articleRepository->find($articleId);
        
        if (!$article) {
            throw new ArticleNotFoundException("Article {$articleId} not found");
        }
        
        $article->publish();
        $this->articleRepository->save($article);
        
        // 清除缓存
        $this->cache->delete("article_{$articleId}");
        $this->cache->delete('recent_articles');
        
        // 触发事件
        $this->dispatcher->dispatch(new ArticlePublishedEvent(
            $article,
            new DateTime()
        ));
        
        return $article;
    }
    
    public function getRecentArticles(int $limit = 10): array {
        $cacheKey = "recent_articles_{$limit}";
        
        return $this->cache->remember($cacheKey, 300, function() use ($limit) {
            return $this->articleRepository->findBy(
                ['status' => 'published'],
                ['published_at' => 'DESC'],
                $limit
            );
        });
    }
}

// 启动应用
$app = new BlogApplication();
$app->run();

架构优势总结

  • 松耦合:各组件通过接口通信,易于测试和维护
  • 可扩展性:通过事件系统和依赖注入轻松添加新功能
  • 可测试性:所有组件都可以被模拟和测试
  • 可维护性:清晰的职责分离和设计模式应用

PHP设计模式实战:构建可维护的企业级应用程序架构
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 php PHP设计模式实战:构建可维护的企业级应用程序架构 https://www.taomawang.com/server/php/1142.html

下一篇:

已经没有下一篇了!

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务