diff --git a/app/Controller/Test/ProxyController.php b/app/Controller/Test/ProxyController.php new file mode 100644 index 0000000..2e5a72b --- /dev/null +++ b/app/Controller/Test/ProxyController.php @@ -0,0 +1,36 @@ +handle(); + } + + /** + * @return array + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + #[RequestMapping(path: 'dynamic', methods: 'GET')] + public function dynamic(): array + { + return (new DynamicProxyService)->handle(); + } +} diff --git a/app/Interface/Test/Proxy/DatabaseQueryInterface.php b/app/Interface/Test/Proxy/DatabaseQueryInterface.php new file mode 100644 index 0000000..e2527c9 --- /dev/null +++ b/app/Interface/Test/Proxy/DatabaseQueryInterface.php @@ -0,0 +1,13 @@ +request(); + + return $this->return->success(); + } +} \ No newline at end of file diff --git a/app/Service/Test/Proxy/Dynamic/DatabaseQueryProxyHandler.php b/app/Service/Test/Proxy/Dynamic/DatabaseQueryProxyHandler.php new file mode 100644 index 0000000..85d6876 --- /dev/null +++ b/app/Service/Test/Proxy/Dynamic/DatabaseQueryProxyHandler.php @@ -0,0 +1,60 @@ +realService = $realService; + $this->logger = $logger; + } + + /** + * @param DatabaseQueryInterface $target + * @param string $method + * @param array $parameters + * @param LoggerInterface $logger + * @return array + */ + public function execute(string $query): array + { + $this->logger->log('Before executing query'.PHP_EOL); + + // 调用原始方法 + $result = $this->realService->execute($query); + + $this->logger->log('After executing query'.PHP_EOL); + + return $result; + } +} \ No newline at end of file diff --git a/app/Service/Test/Proxy/Dynamic/RealDatabaseQueryService.php b/app/Service/Test/Proxy/Dynamic/RealDatabaseQueryService.php new file mode 100644 index 0000000..235a404 --- /dev/null +++ b/app/Service/Test/Proxy/Dynamic/RealDatabaseQueryService.php @@ -0,0 +1,40 @@ +logger->log('Executing query: ' . $query . PHP_EOL); + + return [ + 'result' => 'data', + 'query' => $query, + ]; + } +} \ No newline at end of file diff --git a/app/Service/Test/Proxy/DynamicProxyService.php b/app/Service/Test/Proxy/DynamicProxyService.php new file mode 100644 index 0000000..33db183 --- /dev/null +++ b/app/Service/Test/Proxy/DynamicProxyService.php @@ -0,0 +1,44 @@ +get(RealDatabaseQueryService::class); + + $proxy = new DatabaseQueryProxyHandler( + $realService, + $container->get(LoggerInterface::class), + ); + + return $this->return->success('数据查询成功',$proxy->execute('SELECT * FROM user')); + } +} \ No newline at end of file diff --git a/app/Service/Test/Proxy/Subject/ProxyService.php b/app/Service/Test/Proxy/Subject/ProxyService.php new file mode 100644 index 0000000..4cbfad0 --- /dev/null +++ b/app/Service/Test/Proxy/Subject/ProxyService.php @@ -0,0 +1,67 @@ +realSubjectService = $realSubjectService; + } + + public function request(): void + { + if (!$this->checkAccess()) return; + + $this->realSubjectService->request(); + $this->logAcces(); + + if ($this->checkAccess()) return; + $this->logAcces(); + } + + /** + * @return true + */ + private function checkAccess() + { + $this->logger->log('Proxy: Checking access prior to firing a real request'.PHP_EOL); + return true; + } + + /** + * @return void + */ + private function logAcces() + { + $this->logger->log('Proxy: Logging the time of request'.PHP_EOL); + } +} \ No newline at end of file diff --git a/app/Service/Test/Proxy/Subject/RealSubjectService.php b/app/Service/Test/Proxy/Subject/RealSubjectService.php new file mode 100644 index 0000000..302b3b2 --- /dev/null +++ b/app/Service/Test/Proxy/Subject/RealSubjectService.php @@ -0,0 +1,34 @@ +logger->log($res); + } +} \ No newline at end of file diff --git a/document/proxy.md b/document/proxy.md new file mode 100644 index 0000000..e8577c8 --- /dev/null +++ b/document/proxy.md @@ -0,0 +1,20 @@ + + +### 代理模式 (Proxy Pattern) 详解 + +> 代理模式是一种结构型设计模式,它允许你提供一个代理对象来控制对另一个对象的访问。代理可以在不修改原始对象的情况下,增强或控制对它的访问。 + +#### 核心概念 + +装饰器模式主要解决以下问题: + +- 控制访问:代理可以决定是否允许客户端访问目标对象(如权限控制)。 +- 增强功能:代理可以在调用目标对象前后添加额外逻辑(如缓存、日志、延迟加载)。 +- 远程访问:代理可以代表远程对象(如RPC、数据库访问)。 +- 虚拟代理:代理可以延迟创建开销大的对象(如图片懒加载)。 + +#### 常见应用场景 +- Spring AOP:通过动态代理实现切面编程 +- MyBatis:Mapper接口的代理实现 +- RPC框架:远程服务调用的本地代理 +- 图片懒加载:先显示缩略图代理,点击再加载原图 diff --git a/request/test.http b/request/test.http index f52fd5c..bb441fe 100644 --- a/request/test.http +++ b/request/test.http @@ -30,4 +30,14 @@ Content-Type: application/x-www-form-urlencoded ### Decorator http test GET {{host}}/decorator/test/http +Content-Type: application/x-www-form-urlencoded + + +### Proxy basic test +GET {{host}}/proxy/test/basic +Content-Type: application/x-www-form-urlencoded + + +### Proxy dynamic test +GET {{host}}/proxy/test/dynamic Content-Type: application/x-www-form-urlencoded \ No newline at end of file