面向对象设计的原则------接口隔离原则

来源:互联网 发布:不用网络的音乐播放器 编辑:程序博客网 时间:2024/05/29 18:24

接口隔离原则(Interface Segregation Principle)

1、接口隔离原则的定义:

第一种定义: Clients should not be forced to depend upon interfaces that they don't use.客户端不应该依赖它不需用的接口。

第二种定义:The dependency of one class to another one should depend on the smallest possible interface。一个类对另外一个类的依赖性应当是建立在最小的接口上的。

换句话说,使用多个专门的接口比使用单一的总接口总要好,建立单一接口,不要建立臃肿庞大的接口。一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。不应当将几个不同的角色都交给同一个接口,而应当交给不同的接口。

2、接口污染定义:

所谓接口污染就是为接口添加了不必要的职责。在接口中加一个新方法只是为了给实现类带来好处,以减少类的数目。持续这样做,接口就被不断污染,变胖。实际上,类的数目根本不是什么问题,接口污染会带来维护和重用方面的问题。最常见的问题是我们为了重用被污染的接口,被迫实现并维护不必要的方法。因此,我们必须分离客户程序,分离客户程序就是分离接口。

3、分离接口的实现方法:

分离接口的方式一般分为两种:

1) 使用委托分离接口。(Separation through Delegation

就把请求委托给别的接口的实现类来完成需要的职责,就是适配器模式(Adapter)

2) 使用多重继承分离接口。(Separation through Multiple Inheritance。)

该方法通过实现多个接口来完成需要的职责。

两种方式各有优缺点,通常我们应该先考虑后一个方案,如果涉及到类型转换时则选择前一个方案。

4、实例

假如有一个Door,有lockunlock功能,另外,可以在Door上安装一个Alarm而使其具有报警功能。用户可以选择一般的Door,也可以选择具有报警功能的Door

要遵循ISP设计原则,方案如下:

1、在IAlarm接口定义alarm方法,在IDoor接口定义lockunlock方法。接口之间无继承关系。CommonDoor实现IDoor接口。


public interface IDoor {

    public void lock();

    public void unlock();

}

public interface IAlarm {

    public void alarm();

}

public class CommonDoor implements IDoor {

    public void lock() {

       System.out.println("CommonDoor is lock!");

    }

    public void unlock() {

       System.out.println("CommonDoor is unlock!");

    }

}


AlarmDoor2种实现方案:

1)同时实现IDoorIAlarm接口。

public class AlarmDoor implements IDoor, IAlarm {

    public void lock() {

       System.out.println("AlarmDoor is lock!");

    }

    public void unlock() {

       System.out.println("AlarmDoor is unlock!");

    }

    public void alarm() {

       System.out.println("AlarmDoor is alarm!");

    }

}

2)继承CommonDoor,并实现Alarm接口。该方案是继承方式的Adapter设计模式的实现。

此种方案更具有实用性。

public class AlarmDoor extends CommonDoor implements IAlarm {

    public void lock() {

       super.lock();

    }

    public void unlock() {

       super.unlock();

    }

    public void alarm() {

       System.out.println("AlarmDoor is alarm!");

    }

}

2、采用委让实现


public interface IDoor {

    public void lock();

    public void unlock();

}

public interface IAlarm {

public void lock();

public void unlock();

    public void alarm();

}

public class CommonDoor implements IDoor {

    public void lock() {

       System.out.println("CommonDoor is lock!");

    }

    public void unlock() {

       System.out.println("CommonDoor is unlock!");

    }

}


采用委托的方式即采用对象适配器的方式

public class AlarmDoor implements IAlarm {

    private CommonDoor commdoor=new CommonDoor();

    public void lock() {

       commdoor.lock();

    }

    public void unlock() {

       commdoor.unlock();

    }

    public void alarm() {

       System.out.println("AlarmDoor is alarm!");

    }

}

5、小结

如果已经设计成了胖接口,可以使用适配器模式隔离它。像其他设计原则一样,接口隔离原则需要额外的时间和努力,并且会增加代码的复杂性,但是可以产生更灵活的设计。如果我们过度的使用它将会产生大量的包含单一方法的接口,所以需要根据经验并且识别出那些将来需要扩展的代码来使用它。

原创粉丝点击