我有三门课:
Logger。Checker。Operations。我需要Logger在检查和操作输出(日志)的过程。我需要在操作中检查,以检查数据的有效性。
class Logger {
}
class Checker {
// inherit Logger ?
// dependency-inject Logger ?
// access Logger statically ?
// compose Logger as singleton or create new object ?
}
class Operations {
// inherit Logger ?
// dependency-inject Logger ?
// access Logger statically ?
// compose Logger as singleton or create new object ?
}应用程序将只创建一个操作和检查类实例。问题是-在不需要或创建新对象的情况下,Logger应该是什么类型的类,它应该如何在Operations类中实现?
发布于 2016-01-12 12:28:48
如果您正在为接口编程,那么最灵活的选择是使用一个装饰器:
interface ILogger
{
function log($msg);
}
class FileLogger implements ILogger{
function log($msg)
{
file_put_contents('file.dat', $msg . "\n", FILE_APPEND);
}
}
interface IChecker
{
function check($var);
}
class Checker implements IChecker {
function check($var)
{
//do some checking
return true;
}
}
//decorator
class LoggingChecker implements IChecker
{
private $checker;
private $logger;
function __construct(IChecker $checker, ILogger $logger)
{
$this->checker = $checker;
$this->logger = $logger;
}
function check($var)
{
$checkResult = $this->checker->check($var);
$this->logger->log('check result is: ' . ($checkResult)? 'a success' : 'a failure');
return $checkResult;
}
}
interface IOperations
{
function doOperation($var);
}
class Operations implements IOperations{
private $checker;
function __construct(IChecker $checker)
{
$this->checker = $checker;
}
function doOperation($var)
{
if($this->checker->check($var)){
//do some operation
}
}
}
//composotion root
//create concrete logger, in this case a FileLogger instance, though you could latter create a SqlLogger or EmailLogger
//and swap it without any changes to the other classes
$logger = new FileLogger();
//create concreate checker
$checker = new Checker();
//create decorated checker
$loggingChecker = new LoggingChecker($checker, $logger);
//Operations can now be instantiated with either the regular checker, or the decorated logging checker, and it will
//work just the same, with no knowledge of the existense of loging, or indeed any knowledge of how the checker functions, beyond
//the fact it has a method called check that excepts a single parameter
$operation = new Operations($checker); //no logging is done
//OR
$operation = new Operations($loggingChecker); //logging is done请注意,在上面的长寿示例中,我只为IChecker创建了一个装饰器。
您还可以为IOperations (如LoggingOperations )创建一个装饰器,它的工作方式与ILogger和IOperations的实例相同。您将使用相同的具体ILogger实现($logger)和IOperations实现($operation)实例化它。
使用此对象的类只依赖于IOperations,可以用$operation或$logginOperation实例化,并以相同的方式运行。
希望这个例子能让您了解接口编程的灵活性,以及装饰器模式如何简化依赖类并帮助执行SRP。
发布于 2016-01-11 15:39:14
直接回答你的问题,什么样的课应该是记录员.
真正单例的一个典型例子是日志服务。假设我们有一个基于事件的日志记录服务:客户机对象请求通过向日志记录服务发送消息来记录文本。其他对象实际上通过侦听这些日志记录请求的日志记录服务并处理这些请求,从而将文本记录到某个地方(控制台、文件等)。首先,注意日志记录服务通过了作为单例的经典测试: 请求者需要一个众所周知的对象来将请求发送到日志。这意味着一个全局的接入点。由于日志记录服务是多个侦听器可以注册的单个事件源,所以只需要一个实例。
更多信息请访问为什么我们应该把Logger类看作一个单例呢?
对于一个不错的记录器,如果您没有一个在您的框架中,您应该看看这个克洛格
发布于 2016-01-11 16:59:59
这取决于,是否有可能拥有具有不同属性的记录器对象?(例如,将日志写入其他文件夹或根据它们的属性对要记录的消息做一些不同的操作),如果是这样的话,依赖项注入就是一种方式。
记录器是否以相同的方式执行,甚至不需要属性?(例如,它只是将msg写到相对于源文件夹的预定义文件中)。甚至不需要使用单例,它可能是一个带有静态方法的实用程序类。
最后,如果您的记录器需要初始化,并且您只初始化它一次,那么您可以使用单例。
https://stackoverflow.com/questions/34725357
复制相似问题