2013-03-01 29 views
0

假设您正在编写一个“更大”的应用程序,并且想要在类中记录某些错误。现在几乎每个班级都需要访问记录器。分享重要实例,无需耦合

一个简单的解决办法是以下(PHP,但是这并不重要):

class SomeClass { 
    public function someMethod() { 
    // stuff ... 
    Logger::log("something happened"); 
    // stuff ... 
    } 
} 

这种方法的问题是,它使得它使用记录仪每类依赖于它,你可以在没有Logger的情况下,不要在其他项目中使用相同的类。它紧密结合在一起。如果不更改SomeClass的实施方式,则无法更改消息的记录方式。

该办法的一个“小”的升级上面会如下:

class SomeClass { 

    private $logger; 

    public function __construct(/* stuff */) { 
    $this->logger = LoggerFactory::getLogger(); 
    } 

    public function someMethod() { 
    // stuff ... 
    $this->logger->log("something happened"); 
    // stuff ... 
    } 
} 

这并不能真正解决问题,因为现在SomeClass简单地依赖于LoggerFactory,它的紧耦合到它。好的是,LoggerFactory现在可以返回Logger类的不同实例。所以,如果你想改变消息的记录方式,你不需要改变SomeClass的实现。

的另一种方法将使用依赖注入:

class SomeClass { 

    private $logger; 

    public function __construct(Logger $logger, /* stuff */) { 
    $this->logger = $logger; 
    } 

    public function someMethod() { 
    // stuff ... 
    $this->logger->log("something happened"); 
    // stuff ... 
    } 
} 

现在,这并不夫妇SomeClass于任何特定的类。它只需要一个实现Logger接口的类。但是我遇到的问题是,只要创建对象,就需要将Logger实例传递给构造函数。

$object = new Position($this->logger, $x, $y); 

另一个问题我有这个的是,该记录器是不是真的Position类像$x$y的一部分。这只是一个实用程序。

你如何处理最好的情况?在这种情况下,耦合与内聚之间的最佳折衷是什么?

回答

1

你的做法是正确的答案的控制原理的反转。 但是,正如您所说的,对于应用程序来说,记录器是一个横切关注点,与位置实体无关。换句话说:这纯粹是技术性的,我们不想知道它。

在这里我看到两个选项:

1)你可以通过Manager类某种引用您所有的记录器,并使用你需要在类级别的人。该解决方案中需要记录功能的所有类都必须知道此LoggingManager。在使用外部Logging Frameworks(例如:Log4Net)时,我经常这样做。

2)或者您可以在运行时从更高的实体(服务)请求记录器提供所需的记录器。使用Dependancy Injection Framework或Aspect Oriented编程风格的类配置将从类本身中删除Logger Type(或Factory)的选择。

不幸的是我不熟悉PHP,所以我不能为您提供一个代码示例。 但是我确实在C#中找到了这个AOP的好例子:http://visualstudiomagazine.com/articles/2011/05/12/wccsp_aspect-oriented-programming.aspx

+0

在StackOverflow的另一个线程上找到了一些PHP AOP框架:http://stackoverflow.com/questions/4738282/are-there-任何面向-工作纵横-PHP-库 – Peter 2013-03-01 13:13:35

1

AOP是一个很棒的工具,它可以让您将日志从业务逻辑中分离出来。

使用AOP最常见的一种情况是日志记录,因此值得一看。

你可以分析是否有适合你的需求的框架与它一起玩来看看它是怎么回事。

this link你可以看看如何记录可以使用postsharp来实现,一个C#的AOP框架

+0

这听起来很不错,但是您是否有某种示例,或者您可以指示我从一个位置开始? – MarcDefiant 2013-03-01 12:35:21

+0

我对PHP不太熟悉,你应该尝试找到一个特定的框架。在谷歌搜索'AOP php'可能会帮助 – 2013-03-01 12:42:46

+0

我一定会这么做。但是请注意:这个问题没有用PHP标记,所以如果你可以用你熟悉的语言发布一个例子,那就太棒了,只是为了得到一个基本的想法。这也将为未来的读者提高这个问题/答案的价值。 – MarcDefiant 2013-03-01 12:47:04