语言-编程原则SOLID-ISP

Interface Segregation Principle 接口分离原则

Motivation

When we design an application we should take care how we are going to make abstract a module which contains several submodules. Considering the module implemented by a class, we can have an abstraction of the system done in an interface. But if we want to extend our application adding another module that contains only some of the submodules of the original system, we are forced to implement the full interface and to write some dummy methods. Such an interface is named fat interface or polluted interface. Having an interface pollution is not a good solution and might induce inappropriate behavior in the system.

 

The Interface Segregation Principle states that clients should not be forced to implement interfaces they don't use. Instead of one fat interface many small interfaces are preferred based on groups of methods, each one serving one submodule.

动机

当我们设计一个应用程序时,我们应该注意如何抽象一个包含多个子模块的模块。 考虑到由类实现的模块,我们可以在界面中完成对系统的抽象。 但是,如果我们想要扩展我们的应用程序,添加另一个仅包含原始系统某些子模块的模块,我们不得不实现完整的接口并编写一些虚拟方法。 这样的接口被称为胖接口或污染接口。 界面污染并不是一个好的解决方案,可能会导致系统中不适当的行为。

 

接口隔离原则规定客户端不应该被迫实现他们不使用的接口。 代替一个胖接口,许多小接口基于方法组而优选,每个方法服务于一个子模块。

Below is an example which violates the Interface Segregation Principle. We have a Manager class which represent the person which manages the workers. And we have 2 types of workers some average and some very efficient workers. Both types of workers works and they need a daily launch break to eat. But now some robots came in the company they work as well , but they don't eat so they don't need a launch break. One on side the new Robot class need to implement the IWorker interface because robots works. On the other side, the don't have to implement it because they don't eat.

 

This is why in this case the IWorker is considered a polluted interface.

 

If we keep the present design, the new Robot class is forced to implement the eat method. We can write a dummy class which does nothing(let's say a launch break of 1 second daily), and can have undesired effects in the application(For example the reports seen by managers will report more lunches taken than the number of people).

 

According to the Interface Segregation Principle, a flexible design will not have polluted interfaces. In our case the IWorker interface should be split in 2 different interfaces.

下面是一个违反界面分离原则的例子。我们有一个代表管理工作人员的经理类。我们有两种类型的工人,一些是平均工人,一些是非常高效的工人。两种类型的工作人员都在工作,他们需要每天休息时间、吃东西。但是现在有些机器人进入了他们工作的公司,但他们不吃东西,所以他们不需要休息。一个新的Robot类需要实现IWorker接口,因为机器人工作。另一方面,由于不吃东西,所以不必执行它。

 

这就是为什么在这种情况下IWorker被认为是污染的接口。

 

如果我们保持现在的设计,那么新的Robot类将被迫执行eat方法。我们可以编写一个虚拟类,它什么都不做(假设每天设定1秒休息),并且可能会在应用程序中产生不良影响(例如,管理人员看到的报告会报告比人数多的午餐)。

 

根据界面分离原则,灵活的设计不会有污染的界面。在我们的例子中,IWorker接口应该分成两个不同的接口。

// interface segregation principle - bad example
interface IWorker {
              
public void work();
               public void eat();
}

class Worker implements IWorker{
               public void work() {
                               // ....working
               }
               public void eat() {
                               // ...... eating in launch break
               }
}

class SuperWorker implements IWorker{
               public void work() {
                               //.... working much more
               }

               public void eat() {
                               //.... eating in launch break
               }
}

class Manager {
               IWorker worker;

               public void setWorker(IWorker w) {
                               worker=w;
               }

               public void manage() {
                               worker.work();
               }
}

 

// interface segregation principle - good example
interface IWorker extends Feedable, Workable {
}
  
interface IWorkable {
                 public void work();
}
  
interface IFeedable{
                 public void eat();
}
  
class Worker implements IWorkable, IFeedable{
                 public void work() {
                                 // ....working
                 }
  
                 public void eat() {
                                 //.... eating in launch break
                 }
}
  
class Robot implements IWorkable{
                 public void work() {
                                 // ....working
                 }
}
  
class SuperWorker implements IWorkable, IFeedable{
                 public void work() {
                                 //.... working much more
                 }
  
                 public void eat() {
                                 //.... eating in launch break
                 }
}
  
class Manager {
                 Workable worker;
  
                 public void setWorker(Workable w) {
                                 worker=w;
                 }
  
                 public void manage() {
                                 worker.work();
                 }
}

 

Conclusion

If the design is already done fat interfaces can be segregated using the Adapter pattern.

 

Like every principle Interface Segregation Principle is one principle which require additional time and effort spent to apply it during the design time and increase the complexity of code. But it produce a flexible design. If we are going to apply it more than is necessary it will result a code containing a lot of interfaces with single methods, so applying should be done based on experience and common sense in identifying the areas where extension of code are more likely to happens in the future.

结论

如果设计已经完成,胖接口可以使用适配器模式进行隔离。

 

像每个原理一样,接口隔离原则是一个原则,需要花费额外的时间和精力在设计时间内应用它并增加代码的复杂性。 但它产生了一个灵活的设计。 如果我们打算将它应用到超过必要的程度,它将导致代码包含大量单一方法的接口,因此应根据经验和常识来确定代码扩展可能发生的区域 未来。

 一句话总结:

 其原则就是将接口中的每一个功能拆分成一个接口,比方例子中的eat,work ,这会导致大量的单一方法接口,但也增加了程序的灵活性,需要结合业务来判断。

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值