我理解你的问题。是的,装饰器模式可以帮助您在甚至不同的业务逻辑中重用您的类。
我在所有可能的地方都使用装饰器模式,因为它真的可以帮助你。例如,假设您想从数据库中获取记录列表,为此您正在使用简单的存储库。这将返回您全部或一条记录。像这儿。有关存储库的更多信息,请访问此处。
$repo=new ClientRepository();
$repo->all();
但是,假设您有业务规则,在某些地方您应该记录请求的数据,而在其他地方您应该缓存请求。所以,你会怎么做。当然,大多数人会为 CacheClientRepository 和 LogClientRepository 创建单独的类。可能没问题,但是如果业务规则会同时询问您 Log 和 Cache 那么您将创建什么单独的类,例如 LogAndCacheClientReposiotry(); 如果你这样做,你最终会得到大量重复代码的类。
对于这种情况,最好的解决方案是使用 DecoratorPattern。您将需要创建一个接口并在每个装饰器中实现它。您可以随心所欲地装饰您的存储库。
这是代码示例:
<?php
interface RepositoryInterface
{
public function all();
}
class ClientRepository implements RepositoryInterface
{
public function all()
{
// Your code for database goes here
}
}
class CacheRepository implements RepositoryInterface
{
/**
* @var RepositoryInterface
*/
private $repo;
/**
* CacheRepository constructor.
* @param RepositoryInterface $repo
*/
public function __construct(RepositoryInterface $repo)
{
$this->repo = $repo;
}
public function all()
{
//Code for caching goes here
return $this->cache('cache-all',function(){
return $this->repo->all();
});
}
//......
}
class LogRepository implements RepositoryInterface
{
/**
* @var RepositoryInterface
*/
private $repo;
/**
* LogRepository constructor.
* @param RepositoryInterface $repo
*/
public function __construct(RepositoryInterface $repo)
{
$this->repo = $repo;
}
public function all()
{
//Code for logging goes here
return $this->log('log-all',function(){
return $this->repo->all();
});
}
//......
}
//.. Simple Repository
$repo=new ClientRepository();
//.. Cached Repository
$repo=new CacheRepository( new ClientRepository() );
//.. Logging Repository
$repo=new LogRepository( new ClientRepository() ) ;
//.. Logging and Caching at the same time
$repo=new LogRepository( new CacheRepository( new ClientRepository() ) ) ;
我希望它会对你有所帮助,因为装饰器模式是我所知道的最好的模式之一。