关于OOP中单一职责的困惑

问题描述 投票:0回答:1

让我们考虑以下示例:

class User
{

}

class FirstUseNotification
{
    function show(User user)
    {
        // check if it was already shown, return if so
        // show a notification
        // mark it as shown in the db or whatever
    }
}

class SomeController
{
    function someMethod()
    {
        firstUseNotification->show(user);
    }
}

show()方法似乎通过做三件事打破了单一职责。所以我认为可以这样重写:

class User
{

}

class FirstUseNotification
{
    function show(User user)
    {
        // show a notification
    }

    function shouldShow(User user)
    {
        // return true if not yet shown
    }

    function markAsShown(User user)
    {
        // flag notification as shown
    }
}

class SomeController
{
    function someMethod()
    {
        if (firstUseNotification->shouldShow(user)) 
        {
            firstUseNotification->show(user);
            firstUseNotification->markAsShown(user);
        }
    }
}

所以这就是我感兴趣的内容:

  1. 我是否正确假设第二个示例中的通知类现在可以通过单一职责原则正常?
  2. show()方法中发生的所有事情都消失了,但是……它们只是简单地重定位到控制器中的方法,所以这不意味着该控制器方法现在打破了单一职责吗?如果是这样,如何才能做到这一点?
oop solid-principles single-responsibility-principle
1个回答
0
投票
[单一责任原则(SRP)通常由Robert C. Martin以报价的形式陈述:

一个班级只有一个改变的理由。

在这种情况下,您的FirstUseNotification类的目的是向新用户显示通知。因此,该类需要更改的唯一原因是该目的是否更改;这是原因之一,因此可以满足SRP。

请注意,此定义适用于类,而不适用于方法。就是说,将此方法分为三个方法可能会[违反] SRP,因为如果此类的用户需要调用三个方法而不是一个,则该用户类负责检查是否显示通知,并且如图所示标记用户,

除了用户类的责任。 FirstUseNotification的责任是“向首次使用的用户显示通知”,而不是提供一个API,该API允许其他类在不承担责任的情况下执行此操作。实际上,如果FirstUserNotification类的详细信息如何显示通知或访问数据库,则可能会有其他更改的原因。理想情况下,可以通过为通知和数据库类具有稳定的接口来防止这种情况,以使对那些类的更改不需要更改FirstUseNotification或其他显示通知和/或访问数据库的类。实际上,这并非总是100%实现的,在这种情况下,FirstUseNotification类可能与显示通知或访问数据库的细节有关。但是从理论上讲,如果那些其他阶级适当地处理自己的职责,那么这一阶级只有一个改变的理由。

© www.soinside.com 2019 - 2024. All rights reserved.