发布日期: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();
架构优势总结
- 松耦合:各组件通过接口通信,易于测试和维护
- 可扩展性:通过事件系统和依赖注入轻松添加新功能
- 可测试性:所有组件都可以被模拟和测试
- 可维护性:清晰的职责分离和设计模式应用