我正在尝试使用的Robert C. Martin
原则ISP
。
从维基百科,
ISP最初是由Robert C. Martin在为Xerox咨询时使用和制定的。施乐公司创建了一个新的打印机系统,该系统可以执行诸如装订和传真之类的各种任务。该系统的软件是从头开始创建的。随着软件的增长,进行修改变得越来越困难,因此,即使是最小的更改也要花费一个小时的重新部署周期,这几乎使开发变得不可能。
设计问题是几乎所有任务都使用单个Job类。每当需要执行打印作业或装订作业时,都会调用Job类。这导致了一个“胖”类,其中包含针对各种不同客户的多种方法。由于采用了这种设计,即使没有用到,平常的工作也会知道打印作业的所有方法。
Martin建议的解决方案现在使用了所谓的接口隔离原理。应用到Xerox软件后,使用“依赖倒置原则”在Job类及其客户端之间添加了一个接口层。创建了一个Staple Job接口或Print Job接口,而不是拥有一个大的Job类,这将由Staple或Print类分别调用Job类的方法来使用。因此,为每种作业类型创建了一个接口,这些接口均由Job类实现。
我想了解的是how the system functioned and what Martin proposed to change it
。
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.
我可以尝试到这一点,并被困在这里
an interface layer between the Job class and its clients was added using the Dependency Inversion Principle
-维基百科线-(界面层?)
1Instead 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
-(然后调用Job类的方法-好的,创建单独的接口,然后为什么调用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接口有什么作用,为什么要使用它?可以将其删除对吗?
ISP不是一种设计模式,而是一种设计原则。而且它有助于避免实现客户端不需要的接口。例如,如果您有只需要打印的客户。但是,您可以IJob
使用此客户端不需要的一堆方法进行接口。为什么我会实现DoStaplingJob
,DoJob1
,DoJob2
和DoJob3
如果我只想打印?因此,解决方案是创建一个满足我需求的小界面:
public interface IPrintingJob
{
bool DoPrintJob();
}
原始界面如下所示:
public interface IJob : IPrintingJob
{
bool DoStaplingJob();
bool DoJob1();
bool DoJob2();
bool DoJob3();
}
现在,所有只希望打印的客户端都将实现IPrintginJob
接口,而不必为IJob
接口的其他成员所困扰。IJob
如果您有不需要IJob
接口的全部功能的客户端,则可以继续将接口拆分为较小的接口。
更新:从客户端的角度来看。依靠大接口不是很方便。例如,您有只希望打印的客户。您可以依赖IJob
接口并将Job
类实例传递给此客户端:
public void Foo(IJob job)
{
job. // intellisense will show confusing bunch of members you don't need here
}
对于许多小接口,您只能依赖IPrintingJob
接口,并且仍然通过Job
大类作为该接口的实现:
public void Foo(IPrintingJob printingJob)
{
printingJob. // intellisense will show single member. easy and handy
}
另一个好处是易于重构。稍后,您可以从Job
类到其他小类(例如)提取打印功能PrintingJob
。您将能够将其实例传递给仅需打印的客户端。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句