界面隔离原则是否只是单一责任原则的替代?
我认为如果我的班级满足SRP,则无需提取多个界面。
所以ISP看起来像解决方案,以防我们因某种原因打破SRP。
我是对的吗?
答案 0 :(得分:29)
没有。以一个类为例,该类的职责是持久保存数据。硬盘。将类拆分为读写部分并不具有实际意义。但是有些客户端应该只使用类来读取数据,有些客户端只能用来写数据,有些客户端只能用来读取数据。在这里使用三个不同的接口应用ISP将是一个很好的解决方案。
答案 1 :(得分:18)
我认为如果我的班级满足SRP,则无需提取更多内容 比一个界面。
单一责任原则是一个类(或方法)不应该有多个改变的原因(即每个只负责一个功能)。为了兑现这一点,您将发现自己在系统开发时创建新类。
E.g。如果你开始使用Car
课程&发现你需要改变齿轮的功能,你将把它提取到一个Gearbox
类。这意味着如果更改齿轮更改后面的机制,则不需要更改父Car
类。如果你为你的汽车添加动力转向,你将再次将它提取到它自己的班级。收音机将是另一个班级。
这个抽象级联将在您的Car
课程中发生。当您从Car
本身向下移动时,您会发现每个班级的细节都会增加 - 例如虽然Car
类可能有一个changeGear()
方法允许用户选择要参与的工具,但Gearbox
类将会考虑实现这一点的细节(例如,压低离合器,脱离当前档位,选择新档位等。)
但是,通过OO设计,我们不希望将Gearbox
的详细信息公开给最终用户 - 我们希望它们以高抽象级别与我们的系统交互,而无需知道如何内部工作。我们还希望对这些内部进行封锁,以便我们可以在将来更改它们而无需用户重构其代码(这就是为什么我们将它们标记为private
或protected
)。
因此,我们只允许用户通过Car
类本身与我们的汽车互动。 这个是接口隔离原则的用武之地.SRP确保Car
类将其子组件委托给不同的类,但是我们所有的{{1}仍将通过public
类本身调用方法。 ISP 确保不是将所有这些集中在一个界面中,而是创建逻辑区别&为相关功能公开多个接口。
答案 2 :(得分:1)
没有
一个类可以实现多个接口,但它应该实现仅适用于它的方法。
假设您有10多种不同的功能,例如Climb, Think, Learn, Apply
。类Dog
可以有2个功能,类Cat
可以有2个功能,类Man
可以有6个功能。在各个类中仅实现适用的功能是有意义的。
看看这段代码。
public class ISRDemo{
public static void main(String args[]){
Dog dog = new Dog("Jack",16);
System.out.println(dog);
Learn dl = dog;
dl.learn();
ProtectOwner p = dog;
p.protectOwner();
Cat cat = new Cat("Joe",20);
System.out.println(cat);
Climb c = cat;
c.climb();
Remember r = cat;
cat.doRemember();
Man man = new Man("Ravindra",40);
System.out.println(man);
Think t = man;
t.think();
Learn l = man;
l.learn();
Apply a = man;
a.apply();
PlaySports pm = man;
pm.playSports();
Remember rm = man;
rm.doRemember();
}
}
class Dog implements Learn,ProtectOwner{
private String name;
private int age;
public Dog(String name,int age){
this.name = name;
this.age = age;
}
public void learn(){
System.out.println(this.getClass().getSimpleName()+ " can learn");
}
public void protectOwner(){
System.out.println(this.getClass().getSimpleName()+ " can protect owner");
}
public String toString(){
return "Dog :"+name+":Age:"+age;
}
}
class Cat implements Climb,Remember {
private String name;
private int age;
public Cat(String name,int age){
this.name = name;
this.age = age;
}
public void climb(){
System.out.println(this.getClass().getSimpleName()+ " can climb");
}
public void doRemember(){
System.out.println(this.getClass().getSimpleName()+ " can remember");
}
public String toString(){
return "Cat :"+name+":Age:"+age;
}
}
interface ProtectOwner {
public void protectOwner();
}
interface Remember{
public void doRemember();
}
interface Climb{
public void climb();
}
interface Think {
public void think();
}
interface Learn {
public void learn();
}
interface Apply{
public void apply();
}
interface PlaySports{
public void playSports();
}
class Man implements Think,Learn,Apply,PlaySports,Remember{
String name;
int age;
public Man(String name,int age){
this.name = name;
this.age = age;
}
public void think(){
System.out.println(this.getClass().getSimpleName() + " can think");
}
public void learn(){
System.out.println(this.getClass().getSimpleName() + " can learn");
}
public void apply(){
System.out.println(this.getClass().getSimpleName() + " can apply");
}
public void playSports(){
System.out.println(this.getClass().getSimpleName() + " can play sports");
}
public void doRemember(){
System.out.println(this.getClass().getSimpleName() + " can remember");
}
public String toString(){
return "Man :"+name+":Age:"+age;
}
}
输出:
java ISRDemo
Dog :Jack:Age:16
Dog can learn
Dog can protect owner
Cat :Joe:Age:20
Cat can climb
Cat can remember
Man :Ravindra:Age:40
Man can think
Man can learn
Man can apply
Man can play sports
Man can remember
在上面的示例中,接口隔离建议在10个接口中定义10个功能,而不是在胖接口中声明所有这些功能。但这并不意味着您需要不同的课程来满足单一责任标准。
在同一个示例中查看Dog, Cat and Man
类的实现。