接口隔离原则(ISP)

接口隔离原则(The Interface Segregation Interface)

 

        这个原则用来处理“胖(fat)”接口(类的接口不是内聚的)所具有的缺点。“胖”接口可以分解成多组方法。


考虑一个安全系统,有一些Door对象,可以被加锁和解锁,并且Door对象知道自己开关状态。

public interface Door {
	public void lock();
	
	public void unlock();
	
	public boolean isOpen();
}

考虑一个这样的实现,TimedDoor 如果门开着的时间过长,它就会发出警报声。为了做到这一点,TimedDoor 对象需要和另一个名为Timer 的对象交互。

public interface Timer {
	// 注册超时服务
	public void register(int timeout, TimerClient client);
}

public interface TimerClient {
	// 超时后执行
	public void timeout();
}

如果一个对象希望得到超时通知,它可以调用Timer 的register 函数。我们怎样将TimeClient 类
和TimedDoor 类联系起来,才能在超时时通知到TimedDoor 中相应的处理代码呢?如下是一个容易想到的解决方案。

 这个方案最主要的问题:现在Door 类依赖TimeClient 了。可是并不是所有种类的Door 都需要定时功能。

分离客户就是分离接口

        Door 接口和TimerClient 接口是被完全不同的客户程序使用的。Timer 使用TimerClient,而操作门的类使用Door。既然客户程序是分离的,所以接口也应该保持分离。

客户对接口施加的反作用力

        例如,有些Timer 的使用者会注册多个超时通知请求。比如对于TimedDoor 来说。当它检测到门被打开时,会向Timer 发送一个register() 消息,请求一个超时通知。可是,在超时到达前,门关上了,关闭一会儿后又被再次打开。这就导致在原先的超时到达前又注册了一个新的超时请求。最后,最初的超时到达,TimedDoor 的 timeout() 方法被调用。Door 错误地发出了警报。

        修复,在每次超时注册中都包含一个唯一的 timeoutID 码,并在调用TimerClient 的timeout() 方法时,再次使用该标识码。

public interface Timer {
	// 注册超时服务
	public void register(int timeout, int timeoutID, TimerClient client);
}

public interface TimerClient {
	// 超时后执行
	public void timeout(int timeoutID);
}

        显然,这个改变会影响到TimerClient 的所有使用者。还会影响到Door 以及Door 的所有客户程序。这是僵化性和粘滞性的臭味。

接口隔离原则(ISP)

        不应该强迫客户依赖于它们不用的方法。

1、使用委托分离接口

 

public TimedDoor implements Door {
	
	public void doorTimeout(int timeoutID);
	
	// 其他接口方法实现...
}

public class DoorTimeAdapter implements TimerClient {
	private TimedDoor itsTimeDoor;
	
	public DoorTimeAdapter(TimedDoor theDoor) {
		this.itsTimeDoor = theDoor;
	}
	
	public void timeout(int timeoutID) {
		itsTimeDoor.doorTimeout(timeoutID);
	}
}

2、使用多重继承分离接口(推荐

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值