The SOLID Principles in C# – Interface Segregation
原文地址:http://www.remondo.net/solid-principles-csharp-interface-segregation/
The fourth post in the SOLID by Example series deals with the Interface Segregation Principle (ISP). It states that clients should not be forced to implement interfaces they don’t use. Or as Uncle Bob puts it: Make fine grained interfaces that are client specific.
SOLID示例代码的第四篇我们来讨论接口分离原则(ISP)。所谓接口分离,是指不应该强迫客户类去实现它们不使用的接口。Uncle Bob(Robert C. Martin)给出了另外一种定义:与其使用单一的总接口,不如使用多个专门的接口。
In the following example we have a simple Person class with some obvious person-like methods and properties. We also have a BirthdayCalendar class that has an Add() method to add a person’s birthday to the calendar. The Add() method takes a Person object as a parameter.
在下面的示例中,我们创建了一个Person类,它拥有一些诸如Eat,Play,Sleep等方法和一些附加的属性。另外,我们创建一个表示生日的Calendar类,调用其Add()方法可以将一个person的生日添加至该calendar中。Add()方法接收一个Person对象作为参数。
This makes sure that Person and BirtdayCalendar are tightly coupled. If Person changes, this can have an impact. If we want to add birtdays from entities other than from a Person we’re in trouble. There’s also no need for BirtdayCalendar to know all of Persons interface.
上述做法会导致Person类和Calendar类出现强耦合。对Person类做出修改,将会对Calendar产生影响。如果我们想从一个Person集合中批量的添加生日信息,将会出现更多的麻烦。对于Calendor类来说,没有必要知晓关于Person类的全部接口信息。
This is why some might say that this class has a fat interface. It has a few useless properties and methods for different clients using the interface. To prevent this we let BirthdayCalendar specify an interface that Person must implement. In this case IBirthday with a Name, Age and DayOfBirth property.
不同的客户端使用Person类,会继承到一些无用的属性和方法。这也是为什么有人说Person类拥有一个“胖接口”的原因。为了避免这种情况,我们为Calendor指定一个IBirthDay接口,Person类实现该接口。在IBirthDay接口中,拥有Name,Age和DayOfBirth等属性。
This makes BirthdayCalendar independent of the Person class which makes it easier to maintain and extend. Imagine we also wanted to add the birthdays of pets to the BirthdayCalendar. The Pet class only had to implement the IBirtday interface to achieve that.
上述设计确保了Calendor类和Person类之间的独立性。同时,让Calendar更易维护和扩展。想象一下,如果将来我们需要将Pets的生日添加至Calendar中,仅仅需要Pet类实现IBirthday接口即可。