本文共 2526 字,大约阅读时间需要 8 分钟。
类Client的实例instanceClient希望使用另一个对象instanceX提供的服务service,但在设计时我们并不能确定对象instanceX属于那个类,这时我们将instanceX提供的服务service抽象为一个接口serviceProvider,然后让对象instanceClient通过持有接口serviceProvider的实例来使用服务。这种通过接口间接获得服务的解决方案就是接口模式。
接口模式可以是一个接口抽象一个对象提供的服务,也可以是一组接口抽象一群对象的交互。
适配器模式、外观模式、合成模式、桥接模式。它们本质上都是接口,但是又超越了普通的接口,更为特殊。
抽象类和接口是Java中提供的两种抽象机制。两者之间有联系也有区别,选择接口和抽象类能反映出对于问题领域本质的理解,对于设计意图的理解是否正确合理。
所有的对象都需要用类描述,但并不是所有的类都用来描述对象。如果一个类中没有足够的信息来描绘一个具体的对象,这样的类就是抽象类。面向对象领域,抽象类主要用来隐藏信息,比如三角形、正方形、长方形可以抽象成形状。
//抽象类abstract Class Door { abstract void open(); abstract void close();}//接口interface Door { void open(); void close();}
以上面的门为例,如果我们要添加一个报警的方法alarm()。此时的抽象类和接口就变成了以下:
//抽象类abstract Class Door { abstract void open(); abstract void close(); abstract void alarm();}//接口interface Door { void open(); void close(); void alarm();}------------------------------//实现类:Class A extends Door{ void open(){ .......} void close(){ .......} void alarm(){ .......}}Class A implements Door{ void open(){ .......} void close(){ .......} void alarm(){ .......}}
这种定义实现功能肯定没问题,但是违反了接口隔离原则。
接口隔离原则(Interface Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。每一个接口应该承担一种相对独立的角色,不干不该干的事,该干的事都要干。这里具体指Door的定义和功能(行为方法)都放到了一起。由于类不能多继承,拆开放到两个抽象类肯定不行。如果放到两个接口功能上没问题,但对问题领域的概念本质理解出现了偏差。A本质上是一个门,同时具有报警的功能。对于Door的概念应是is-a的关系,所以用抽象类定义。
另外A又具有报警功能,说明又能完成报警概念中定义的行为,所以报警概念通过interface定义。//抽象类abstract Class Door { abstract void open(); abstract void close();}//接口interface Alarm { void alarm();}//实现Class A extends Door implements Alarm{ void open(){ .......} void close(){ .......} void alarm(){ .......}}
这种实现方式基本上能够反映出我们对于问题领域的理解,正确的揭示我们的设计意图。抽象类和接口有很大的相似性,但是对于他们的选择又往往反映出问题领域中概念本质的理解、对于设计意图的反映是否正确合理。因为它们表现了概念之间的不同的关系(即使都能实现需求的功能)。
上一篇:
下一篇:转载地址:http://dlrai.baihongyu.com/