Follow me on GitHub Follow me on Twitter

向接口编程,而不是(它的)实现


  设计模式是什么?引用设计模式奠基经典中的话:
  Each pattern describes a problem which occurs over and over again in our enviroment,and then describes the core of the solution to that problem,in such a way that you can use the solution a million times over,without doing the same way twice. 
  熟悉了设计模式可以避免我们重复的造轮子,当我们对问题的理解上升到一定层次,亦可以制定一些用于解决问题的模式。
  设计模式其实并不是解决问题的方法,它用于“如何更好的解决问题”。
  这位老兄 http://blog.csdn.net/beidou321/article/details/6472443 说得很好,在开始前先贴出他博文的网址。
正文:  
  本文并不是直接讲某个模式,而是谈一个原则。
  直接以例子说起,下图是一个再普通不过的情况了,父类车,有很多子类。让我们引入一个问题,假设我们要让车实现加油或者充能,即子类实现RestoreEnergy,那么应该怎么做呢?

  

  似乎父类加一个方法就能解决问题了。

  

  可是,就在我们加完这个方法的时候,惊奇的发现有一个子类叫做。。。。。

  

  木头车是根本不需要RestoreEnergy的,这怎么办呢。

  方法一:

  在木头车类中重写RestoreEnergy()方法,在方法中什么都不做。

  先不讨论这种做法会导致丑陋的代码,加入我们又有个塑料车,那么是不是又要重写RestoreEnergy,如果在工程中做法极多的话,我们会发现用了很多不必要的时间来检测是否存在这样的关系。

  方法二:

  在子类中写RestoreEnergy,去掉父类的RestoreEnergy。

  但是有很多车都是充天然气的,很多车都是加油的,这样办的会在不同的子类中会出现重复的实现代码。

  

  切入正题,”面向接口编程“是如何解决这个问题的呢,首先我们就要谈谈什么地方要面向接口编程”会变动的地方“,对于Car类,所有的Car 的Start 与Stop都是一样的(知道此处有漏洞,请不要找茬。。。)但是它们的RestoreEnergy是”会变化“的,对于这种”会变化“的部分,我们要单独抽离出来,将它们”面向接口编程“

  

  现在的RestoreEnergy方法是调用IEnergySupply接口中的RestoreEnergy方法来实现,我们可以在父类的构造函数中将具体的IEnergySupply实例传入,如:

    class Truck : Car
    {
        public Truck():base(new Gas())
        {
        }
    }

  这样做的结果是:1.实现部分的代码没有重复。2.如果再有车用太阳能,我们只需要再做一个实现IEnergySupply接口的Sun类就可以了。

  通过接口,我们可以做到不关心上层是如何实现的。

  博主是电子出身,之前一直没理解这句话,认为这句话理所当然,代码之间当然不关心如何实现啦。

  其实不然,对于OOP来说,此处的不关心如何实现,就是:根本实例化的类是什么,只管调用RestoreEnergy就好了。

 

  PS:面向接口编程并不是仅仅指的是JAVA C# 中的interface。援引head first design pattern 中的话:

  ”The point is to exploit polymorphism by programming to supertype so that the actual runtime obejct isn't locked into the code“

  所谓的supertype指的是实例化的对象一定会完成的功能,显然interface提供了这种特性,但是并不是说必须要有interface特性才能实现面向接口编程,javascript同样也可以面向接口编程。

 

posted @ 2014-11-22 21:40  官文祥  阅读(313)  评论(0编辑  收藏  举报