Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 接口隔离原则是关于类还是对象?_C#_Oop_Design Patterns_Solid Principles_Interface Segregation Principle - Fatal编程技术网

C# 接口隔离原则是关于类还是对象?

C# 接口隔离原则是关于类还是对象?,c#,oop,design-patterns,solid-principles,interface-segregation-principle,C#,Oop,Design Patterns,Solid Principles,Interface Segregation Principle,提醒(从): 接口隔离原则(ISP)规定,任何客户端都不应 被迫依赖于它不使用的方法 现在看看我的例子 这是我的可变实体。它是从某处编辑的,可以通过只读界面通知更改: interface ICounter { event Action<int> NewNumber; } class Counter : ICounter { public event Action<int> NewNumber; int number = 0; publi

提醒(从):

接口隔离原则(ISP)规定,任何客户端都不应 被迫依赖于它不使用的方法

现在看看我的例子

这是我的可变实体。它是从某处编辑的,可以通过只读界面通知更改:

interface ICounter
{
    event Action<int> NewNumber;
}

class Counter : ICounter
{
    public event Action<int> NewNumber;

    int number = 0;
    public void IncrementAndSend(int x)
    {
        number += x;
        if (NewNumber != null) NewNumber(number);
    }
}
  • ISP是关于真实对象的。你不能使用“过度” 对传入参数的引用
  • ISP是关于课程的。如果您的类已经使用完整接口 在某些地方,不需要在特定方法中限制引用类型。
    i计数器
    接口在本例中过多
  • 从坚实的角度来看,这种架构是完全错误的 原则(为什么?)

  • 我认为最好将IncrementAndSend方法添加到接口中,并使OneToManyRouter类依赖于IEnumerable。 我认为这不是ISP违规,因为NewNumber事件操作和IncrementAndSend方法是严格相关的。
    希望它能对您有所帮助。

    ISP既不是关于类,也不是关于对象,而是关于接口,特别是关于接口设计。该原则旨在阻止在单个接口中对半相关方法进行分组,以避免用户只需要这些方法的子集就可以将其余部分作为空函数实现(抛出
    NotImplementedException
    或将其保留为空:
    {}
    )。因此,更容易实现更连贯的类并更有效地使用接口

    在您的示例中,您将
    计数器
    类与
    ICounter
    接口结合在一起,其方式与ISP概念没有直接关系:

  • ISP是关于真实对象的。不得对传入参数使用“过多”引用
  • 这在一定程度上是正确的(如果我正确解释了“过度”的概念)。然而,正如我提到的,ISP不是关于如何与真实对象交互,而是如何定义一个有用的接口

  • ISP是关于课程的。如果您的类已经在某处使用了完整接口,则无需在特定方法中限制引用类型。在此示例中,ICounter接口过多
  • 这是不对的。如果在具体类上而不是在接口上创建依赖项,那么类实现接口的事实并不意味着什么。请记住,接口通过使组件依赖于契约而不是将来可能更改的特定实现,提供了程序各个部分的解耦。通过使用混凝土类,您将失去这一好处。同样,这与ISP的概念并不完全相关

  • 从坚实的原则来看,这种架构是完全错误的(为什么?)

  • 从强调坚实原则的架构角度来看,我建议依赖于
    I计数器
    ,而不是
    计数器
    ,并将
    递增和发送
    作为接口定义的一部分。

    我不理解严格的关系。为什么它很重要?我通常没有包含不相关成员的类……接口方法之间的“严格关系”之所以如此重要,是因为允许实现接口的具体类定义具体方法,而不需要空的或未实现的方法。这意味着您正在使用接口定义的角色定义良好,对您的对象域非常有用。
    class OneToManyRouter
    {
        IEnumerable<Counter> _destinations;
    
        public OneToManyRouter(IEnumerable<Counter> destinations)
        {
            _destinations = destinations;
        }
    
        // 1         
        public void Attach_1(ICounter source)
        {
            source.NewNumber += (n) =>
            {
                foreach (var dest in _destinations) dest.IncrementAndSend(n);
            };
        }
    
        // 2 
        public void Attach_2(Counter source)
        {
            source.NewNumber += (n) =>
            {
                foreach (var dest in _destinations) dest.IncrementAndSend(n);
            };
        }
    }