c# - 在 C# 中实现 ISP 设计模式

标签 c# oop interface solid-principles

我正在尝试使用 ISPRobert C. Martin 原理。

来自维基百科,

The ISP was first used and formulated by Robert C. Martin while consulting for Xerox. Xerox had created a new printer system that could perform a variety of tasks such as stapling and faxing. The software for this system was created from the ground up. As the software grew, making modification became more and more difficult so that even the smallest change would take a redeployment cycle of an hour, which made development nearly impossible.

The design problem was that a single Job class was used by almost all of the tasks. Whenever a print job or a stapling job needed to be performed, a call was made to the Job class. This resulted in a 'fat' class with multitudes of methods specific to a variety of different clients. Because of this design, a staple job would know about all the methods of the print job, even though there was no use for them.

The solution suggested by Martin utilized what is called the Interface Segregation Principle today. Applied to the Xerox software, an interface layer between the Job class and its clients was added using the Dependency Inversion Principle. Instead of having one large Job class, a Staple Job interface or a Print Job interface was created that would be used by the Staple or Print classes, respectively, calling methods of the Job class. Therefore, one interface was created for each job type, which were all implemented by the Job class.

我想了解的是系统是如何运作的,以及 Martin 提出的改变它的建议

interface IJob
{
    bool DoPrintJob();
    bool DoStaplingJob();
    bool DoJob1();
    bool DoJob2();
    bool DoJob3();
}

class Job : IJob
{
  // implement all IJob methods here.
}

var printClient = new Job(); // a class implemeting IJob
printClient.DoPrintJob();  // but `printClient` also knows about DoStaplingJob(), DoJob1(), DoJob2(), DoJob3() also.

我本可以尝试到这里,但卡在了这里

Job 类及其客户端之间的接口(interface)层是使用依赖倒置原则添加的 - 维基百科行 - (接口(interface)层?)

1创建了一个 Staple Job 接口(interface)或 Print Job 接口(interface),而不是拥有一个大型 Job 类,分别由 Staple 或 Print 类调用 Job 类的方法调用 Job 类的方法 - ( 然后调用 Job 类的方法 - 好的,创建单独的接口(interface)然后为什么要调用 Job 类的方法?)

马丁接下来做了什么? (一些更正的代码框架可以帮助我理解这一点)。

根据回答,我可以进行如下操作。谢谢谢尔盖和克里斯托。

interface IPrintJob
{
  bool DoPrintJob();
}

interface IStapleJob
{
  bool DoStapleJob();
}

interface IJob : IPrintJob, IStapleJob
{
  bool DoPrintJob();
  bool DoStaplingJob();
}

var printClient = new PrintJob(); //PrintJob implements the IPrintJob interface 
var stapleClient = new StableJob(); // StapleJob implements the IStapleJob interface

好的。 IJob 接口(interface)做什么,为什么使用它?它可以删除吗?

最佳答案

ISP 不是一种设计模式——它是一种设计原则。它有助于避免实现客户不需要的接口(interface)。例如。在您的情况下,您的客户只需要打印。但是您有 IJob 接口(interface),其中包含此客户端不需要的一堆方法。如果我只想打印,为什么要实现 DoStaplingJobDoJob1DoJob2DoJob3?因此,解决方案是创建满足我需要的小界面:

public interface IPrintingJob
{
   bool DoPrintJob();
}

原始界面如下所示:

public interface IJob : IPrintingJob
{
    bool DoStaplingJob();
    bool DoJob1();
    bool DoJob2();
    bool DoJob3();
}

现在所有只需要打印的客户端都将实现IPrintginJob 接口(interface),而不会被IJob 接口(interface)的其他成员打扰。如果您的客户端不需要 IJob 接口(interface)的全部功能,您可以继续将 IJob 接口(interface)拆分为更小的接口(interface)。

更新:从客户的角度来看。依赖大接口(interface)不是很方便。例如。您有只需要打印的客户。您可以依赖于 IJob 接口(interface)并将 Job 类实例传递给此客户端:

public void Foo(IJob job)
{    
    job. // intellisense will show confusing bunch of members you don't need here
}

对于许多小接口(interface),您可以仅依赖于IPrintingJob 接口(interface),并仍然传递大的Job 类作为该接口(interface)的实现:

public  void Foo(IPrintingJob printingJob)
{
    printingJob. // intellisense will show single member. easy and handy
}

另一个好处是易于重构。稍后您可以将打印功能从 Job 类提取到其他小类,如 PrintingJob。您将能够将其实例传递给只需要打印的客户端。

关于c# - 在 C# 中实现 ISP 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23217485/

相关文章:

c# - .Net 4 : How to reference a dynamic object with property named "return"

javascript - 为什么在 OOP javascript 中使用 object.prototype.constructor ?

javascript - 如何通过对象传递回调的结果?

java - 为什么抽象方法必须由第一个具体类来实现,而不是由链下的一个更远的类来实现?

PHP 接口(interface) : Specify ANY visibility

java - 接口(interface)的变量在JAVA中是如何工作的,如何调用接口(interface)的方法?

c# - 从 MVC 放置/发布后如何获得 JSON 响应

c# - DELETE 方法 .NET WebAPI 不起作用

Go 工厂方法返回类型接口(interface),而不是实现接口(interface)的结构

c# - C# 中的可空 DateTime