此系列文章来源于我和jason网友的一次关于委托的对话,本来网上关于委托的文章实在是太多了,我也不想去写这方面的东西。但是给jason网友解释委托的那次对话却显得非常的有趣,在jason的建议下便整理成了这一系列文章,其中很多可能与委托并没有什么关系(只是因为它是从一次有关委托的对话而来),纯属本人的一些看法,如有说的不对的地方还请大家指正。

开关的诞生

    话说在一个紧耦合的世界,有一个名为tmfc的工匠,一天,他发明了一个叫做开关的的设备。他琢磨了老半天,决定把开关装在自己的床头,这样他就不用在睡前起床去拔电灯的电线了(这可是个紧耦合的世界啊),tmfc对自己的发明非常满意。

class Switch{
    Light light;
    public void Switch(Light l){
        light = l;
    }
    public void TurnOn(){
        light.On();
    }
    public void TurnOff(){
        light.Off();
    }
}

    tmfc发明了开关的事情很快在他的朋友圈中传了开来,大家都对这个好东西非常感兴趣,一个朋友的朋友的朋友,电风扇厂的老板,听说了这个消息之后兴奋的马上开着他的BMW(传说中的“别摸我”)来到tmfc的住处表示愿意用此车来交换一个能装在他们的风扇上的开关。
    tmfc虽然对这位朋友没什么好感,但是名车的诱惑还是难挡,于是他爽快的答应了下来,过了两天(这两天中,tmfc花了一天半开车到处去兜风^_^),老板就拿到了非常好用的风扇开关。

class FanSwitch{
    Fan fan;
    public void FanSwitch(Fan f){
        fan = f;
    }
    public void TurnOn(){
        fan.On();
    }
    public void TurnOff(){
        fan.Off();
    }
}

基板和接口

    电风扇厂的技师们没费多大力气就把开关装在了风扇上,风扇推出后及其的受欢迎,老板朋友很快买了新款的Benz,而tmfc也由于发明开关而变得名声大噪,来自全国各地的合作请求络绎不绝,tmfc很快便厌倦了重复的生产(已经不能称这种行为为设计了)不同开关的生活,作为一个聪明人(同时也是一个懒人),他很自然的想到了“为什么我不设计一种通用的开关呢?”。没过多久(当然,他是聪明人嘛!)tmfc有了这样的设计:

abtract class AbstractSwitch{
    abstract public void TurnOn();
    abstract public void TurnOff();
}

    他对所有的客户展示了他那优雅而简洁的设计,他声称只要客户的产品从简单的使用AbstractSwitch基板作为他们产品的基板,就可以非常容易的拥有开关的功能,而不必在这里等待他一个个的完成不同的开关产品。“我们的产品已经有基板了,而我们使用的流水线不支持多基板!!”,“我们的产品非常小,无法使用这么大的基板!!”,“使用基板我们的成本提高了一倍!!”,对于这个方案,客户们显然十分不满。面对这个结果,tmfc显得有些意外,但是作为一个优秀工匠(也许我们应该现在应该称他为工程师了),他很快就拿出了更好的解决方案。

Interface ISwitchable{
    On();
    Off();
}

class InterfaceSwitch{
    ISwitchable target;
    public void InterfaceSwitch(ISwitchable t){
        target = t;
    }
    public void TurnOn(){
        t.On();
    }
    public void TurnOff(){
        t.Off();
    }
}

    这次,不需要使用基板,只要增加一个额外的和开关之间的接口就可以在设备上使用开关了,“这下大家满意了吧!”tmfc边咕哝着边给客户们演示了他的新设计。不出所料,大部分的客户感到很满意,虽然需要额外的接口,但还在接口还算便宜,体积也非常的小巧。大部分的客户都愉快的拿着开关和接口走了(剩下那些不是很满意的为了不惹恼它们这个世界上唯一能给他们开关的人,也不得不拿着接口和开关回去想办法说服老板接受这个方案),tmfc也重新开始了开着BMW兜风的日子。

 

故事背后的故事:

  1. 风扇厂老板拿到的显然是最紧偶合的设计,但是我们不能说tmfc不聪明,没有作出更好的设计,因为没有需求上的改变,当时他只看到了这一个需求,并且不需要更改,如果当风扇厂老板找到他是就给出最后的接口的设计,那我们可以说这是一种过度设计.
  2. 关于基板(也就是我们所谓的基类),这个设计比其风扇厂老板的开关是松散了一点,但是无法满足他所面临的需求(这次的需求变化是相当的大),所以,聪明的tmfc同学很快的适应了需求的变化,改变了设计,使用了接口.
  3. 最后的接口设计上我们可以看到,由于加入了组合(这里使用了策略模式),这种方案比基板更加松散,但是这种方法并不是最松偶合的关系,这并不是因为tmfc不聪明,这恰恰是他聪明的地方,为什么这样说,且听下回分解.
 

问题:

  1. tmfc使用继承到底错在哪里?为什么客户会强烈反对?
  2. 使用了接口,客户都满意了(起码没有反对的了),请问使用接口和使用继承的本质区别在哪里?
  3. 哪类客户会对使用接口感到不满意?设想一种使用此接口无法满足的情况.
  4. 上面提到了接口不是最松散的,那更松散的什么(答案在本文中找,哈哈)?为什么使用那种方法更松散呢?
posted on 2006-09-10 20:25  tmfc  阅读(3200)  评论(15编辑  收藏  举报