现在的位置: 首页 > 综合 > 正文

面向对象理论(7)-Interface Programming-[B]

2013年03月23日 ⁄ 综合 ⁄ 共 1849字 ⁄ 字号 评论关闭

面向接口编程(B)

约束的理解是一个很辩证的问题,我觉得我们需要一个好的例子才能把这个事情论述清楚。我很喜欢鸟儿在天上飞这个例子,因为它和大自然紧紧的联系了起来。

class
 Bird
{
    fly() { 

/*
 some code make birds fly on the sky 
*/
 }
}


class
 Dove : Bird
{
    fly() { 

/*
 some code make a dove fly on the sky 
*/
 }
}


class
 Penguin : Bird
{
    fly() { 

/*
 fly, fly, Oh, could I fly? 
*/
 }
}



在这段代码中,有一个基类,class Bird,鸟类,然后派生类是Dove(鸽子),和Penguin(企鹅)。简而言之,这三个类描述了这样一个世界,“但凡是个鸟就能飞
”。哦,世界还是我们所认识的世界嘛?不,企鹅都能飞了?!

问题的关键就在于:“是鸟就一定能飞嘛?”
显然不是,这个世界除了企鹅外,还有许多鸟类没有飞行的能力。也就是说鸟类(Bird)与飞行(fly())并没有一种必然的关系的。或许,我们不该把
fly()方法设计到Bird类中去。于是,我们采用一个叫做IFly的接口,根据can-do的对象关系。我们可以称这个接口的实现类为能飞的事物。

class
 Bird
{
}


interface
 IFly
{
    fly() { 

/*
 some code make something been in the sky 
*/
 }
}


class
 Dove : Bird, IFly
{
    fly() { 

/*
 some code make a dove been in the sky 
*/
 }
}


class
 Penguin : Bird 
/*
 don't implements IFly 
*/

{
}


这就是我们重新刻画的世界。
并且,在这之后,我们发现这样的世界(设计)很好,我们可以很简单地让一些不是鸟类的动物也飞了起来。

class
 Butterfly : Insect, IFly
{
    fly() { 

/*
 a butterfly flies 
*/
 }
}



嗯,这次演化,和Shape类演化到IDraw接口,具有相似的原因。
一些Java,或者C#的教科书,往往会这样写:“Java不支持多继承,但是支持实现多个接口...
...”,我以为这样的话本身没有问题,但是许多初学者会误以为实现多个接口也能完成多继承的功能。而从设计的角度来说,用聚合来代替继承才是一种选择,
这个是我们前面说过的,而实现多接口并不是完成这种对象关系表达的合理途径。因为接口的语义往往是can-do,而且需要强调的是,这是一种约束的语义。
而继承表达的是is-a的关系。继承的对象关系使得派生类传承了一种(行为)能力。而,接口没有。

我们想想,是IFly使得一只鸟儿飞上了天嘛?不,它没有赋予鸟儿这种行为能力。而真正完成飞行能力的是实现代码本身,而并不是“实现接口”这一举动。

想飞?这很容易。
许多动态的教本语言,比如Ruby,Python,JavaScript,它们只要拥有了fly这样的方法,就可以被调用了,于是,无论有没有实现IFly接口,对象都起飞了。所以说,实现接口并没有赋予对象以能力,而是约束对象,或者说要求对象具有某种能力。
一些语言,如果只支持单继承,比如Ruby,如果想聚合某种功能,可以通过Mixins来完成这种功能的扩展。

class



Bird
end


module


Action
  def fly
  end
end


class



Dove 
<
 Bird
 

include


Action

end




dove 

=
 Dove
.
new
dove

.
fly












接口与应用

前面我们所讲的东西足够理论了,但是实际的软件中,大量用到面向接口编程,而没有我们这么多推演和辩证的过程。因为接口有许多重要的性质。
例如,COM的出现,可以解决DLL Hell的问题。结果,COM的开发者总是要定义出许多的COM接口。而它们的实现反而并不重要了。
接口的使用,会有许多种原因,有时候仅仅就是为了做到“接口和实现分离”。而这给软件工程带来了许多新话题。而相当多的设计模式都是以接口编程为基础的,
经典的设计模式的实现,往往就是一个精彩的接口展示。而又不仅仅是模式本身,还有些原则,比如DIP,往往是采用接口编程的方式。当然了DIP还有很多争
论,我们就不讨论它本身的问题了。


这一节,实际上是从反面论证了接口的约束性。

【上篇】
【下篇】

抱歉!评论已关闭.