首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >依赖注入与抽象类与继承与单例

依赖注入与抽象类与继承与单例
EN

Stack Overflow用户
提问于 2016-01-11 15:36:24
回答 3查看 670关注 0票数 2

我有三门课:

  • 将处理信息记录到文件的Logger
  • 验证输入数据的Checker
  • 对输入数据执行操作的Operations

我需要Logger在检查和操作输出(日志)的过程。我需要在操作中检查,以检查数据的有效性。

代码语言:javascript
复制
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类中实现?

EN

回答 3

Stack Overflow用户

发布于 2016-01-12 12:28:48

如果您正在为接口编程,那么最灵活的选择是使用一个装饰器:

代码语言:javascript
复制
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 )创建一个装饰器,它的工作方式与ILoggerIOperations的实例相同。您将使用相同的具体ILogger实现($logger)和IOperations实现($operation)实例化它。

使用此对象的类只依赖于IOperations,可以用$operation$logginOperation实例化,并以相同的方式运行。

希望这个例子能让您了解接口编程的灵活性,以及装饰器模式如何简化依赖类并帮助执行SRP。

票数 1
EN

Stack Overflow用户

发布于 2016-01-11 15:39:14

直接回答你的问题,什么样的课应该是记录员.

真正单例的一个典型例子是日志服务。假设我们有一个基于事件的日志记录服务:客户机对象请求通过向日志记录服务发送消息来记录文本。其他对象实际上通过侦听这些日志记录请求的日志记录服务并处理这些请求,从而将文本记录到某个地方(控制台、文件等)。首先,注意日志记录服务通过了作为单例的经典测试: 请求者需要一个众所周知的对象来将请求发送到日志。这意味着一个全局的接入点。由于日志记录服务是多个侦听器可以注册的单个事件源,所以只需要一个实例。

更多信息请访问为什么我们应该把Logger类看作一个单例呢?

对于一个不错的记录器,如果您没有一个在您的框架中,您应该看看这个克洛格

票数 0
EN

Stack Overflow用户

发布于 2016-01-11 16:59:59

这取决于,是否有可能拥有具有不同属性的记录器对象?(例如,将日志写入其他文件夹或根据它们的属性对要记录的消息做一些不同的操作),如果是这样的话,依赖项注入就是一种方式。

记录器是否以相同的方式执行,甚至不需要属性?(例如,它只是将msg写到相对于源文件夹的预定义文件中)。甚至不需要使用单例,它可能是一个带有静态方法的实用程序类。

最后,如果您的记录器需要初始化,并且您只初始化它一次,那么您可以使用单例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34725357

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档